@devflow-tools/cli 0.19.0 → 0.19.2

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,17 +1,17 @@
1
- import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {existsSync,mkdirSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {DatabaseSync}from'node:sqlite';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function U(n){return Buffer.from(n,"utf8").toString("base64url")}function Re(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r),r}beginContextInitialization(e,t){let o=this.registerSession(e);return o.contextInitialization={startedAt:Date.now(),...t?{toolUseId:t}:{}},o.lastActivityAt=Date.now(),this.persist(o),o}completeContextInitialization(e,t){let o=this.get(e);return o?(t&&o.contextInitialization?.toolUseId&&o.contextInitialization.toolUseId!==t||(delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o)),o):null}bindTaskIdentity(e,t){let o=this.registerSession(e);return o.activeTurnId=t.turnId,o.activeRequestId=t.requestId,o.intentArtifactHash=t.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync$1(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,delete t.contextInitialization,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Re(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`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(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(e,t){let o=this.get(e),r=o?.evidenceDegradations.find(s=>s.obligationId===t);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${U(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",U(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync$1(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).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$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=ke(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??o?.attempt??0;if(t.kind==="resolve"&&o?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(o)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:r?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!Y(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function ke(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let r={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return Y(e.contract)?{kind:t,...r,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...r,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...r}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...r,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function Y(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return 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(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Ne=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Le();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.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 qe(o,n,e,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){l=m instanceof Error?m:new Error(String(m)),u<s&&await He(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(X(n,l),T("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 Le(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function qe(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,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":Ne,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let m=u.statusCode??0;l(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),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 X(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${e.message}
2
- `;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(t,o);}catch{}}function He(n){return new Promise(e=>setTimeout(e,n))}function te(n,e){let t=We(n);mkdirSync(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function We(n){return join(w(n),"session-finalize-pending")}var p=emitSemanticControlLog;function M(n){let{projectRoot:e,...t}=n;try{return new O(e).dispatchBoundary(t).snapshot??null}catch(o){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,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 O=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=Ze(e.kind,e.payload??{});if(!t)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=Xe(o,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${r.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function Xe(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,o=e.turnId??t?.canonicalAction?.binding.turnId,r=e.requestId??t?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.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 Ze(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var rt=512*1024,it=500;var st=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ie(n){let e=n.runtimeStore??new I(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return at(n,e),null;let o=$(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=se(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId),x(n,s,"satisfied",r);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a}),x(n,s,"correction_requested",r,a);continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved"),x(n,s,"degraded",r,a);}return i.length===0?null:ct(i)}function at(n,e){let t=(e.get(n.sessionId)?.evidenceDegradations??[]).filter(i=>i.contract).slice(-8);if(t.length===0)return;let o=t.map(i=>({obligationId:i.obligationId,contractId:i.contractId,contract:i.contract,promptedAt:i.degradedAt,attempt:i.attempt,correctionRequested:true,violations:[]})),r=$(n.transcriptPath,o);if(!(!r.answer||!r.fingerprint))for(let i of o)se(r.answer,[i]).length>0||e.resolveDegradedEvidence(n.sessionId,i.obligationId)&&x(n,i,"satisfied",r.fingerprint);}function x(n,e,t,o,r=[]){t!=="correction_requested"&&M({projectRoot:n.projectRoot,sessionId:n.sessionId,kind:t==="satisfied"?"verification.succeeded":"verification.failed",payload:{receiptId:e.obligationId,reasonCode:t==="satisfied"?"performance_evidence_satisfied":"performance_evidence_unresolved"},dedupeKey:`${e.obligationId}:${t}:${e.attempt}`,producer:"devflow-evidence-contract"}),p({event:"verification.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:t==="satisfied"?"info":t==="degraded"?"error":"warn",timestamp:Date.now(),data:{stage:"performance_evidence_transition",status:t,contractId:e.contractId,obligationId:e.obligationId,attempt:e.attempt,answerFingerprint:o,violations:r,supersedesDegradation:t==="satisfied"&&e.attempt>0}});}function ct(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
1
+ import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {existsSync,mkdirSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {DatabaseSync}from'node:sqlite';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function U(n){return Buffer.from(n,"utf8").toString("base64url")}function Re(n,e,t){let r=e?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash$1("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=t,o.requiredMcpTools=[...new Set(r)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(e,t){let r=this.registerSession(e);return r.contextInitialization={startedAt:Date.now(),...t?{toolUseId:t}:{}},r.lastActivityAt=Date.now(),this.persist(r),r}completeContextInitialization(e,t){let r=this.get(e);return r?(t&&r.contextInitialization?.toolUseId&&r.contextInitialization.toolUseId!==t||(delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r)),r):null}bindTaskIdentity(e,t){let r=this.registerSession(e);return r.activeTurnId=t.turnId,r.activeRequestId=t.requestId,r.intentArtifactHash=t.intentArtifactHash,r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let r=this.sessions.get(t);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(t);if(!existsSync$1(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let r=structuredClone(t);return delete t.executionId,delete t.skillName,delete t.contextInitialization,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),r}addEvidenceObligation(e,t,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Re(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:r,contract:t},`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(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,r,o,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(o)?o:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:r.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===t);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}resolveDegradedEvidence(e,t){let r=this.get(e),o=r?.evidenceDegradations.find(s=>s.obligationId===t);if(!r||!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,t,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${U(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",U(e))}appendEvidenceEvent(e,t,r){let o=this.evidenceJournalDir(e);mkdirSync$1(o,{recursive:true,mode:448});let i=createHash$1("sha256").update(r).digest("hex"),s=join$1(o,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let r;try{r=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let o=r.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=ke(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of o)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let r=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(r)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let o=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!o||r||o.correctionFingerprint===t.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=t.at,o.correctionFingerprint=t.fingerprint,o.violations=t.violations;return}let i=o?.attempt??r?.attempt??0;if(t.kind==="resolve"&&r?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(r)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:o?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),r=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384}),renameSync$1(r,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!Y(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),o=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function ke(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let o={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return Y(e.contract)?{kind:t,...o,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...o,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...o}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...o,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function Y(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,r=e.prohibitedClaims;return 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(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var Ne=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let r=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Le();if(!r)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(r,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 qe(r,n,e,o),a&&registerRuntimeHttpSuccess(r,n).transitioned&&T("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){l=m instanceof Error?m:new Error(String(m)),u<s&&await He(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(r,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(X(n,l),T("http_circuit_transition",{endpoint:r,path:new URL(n,r).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 Le(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function qe(n,e,t,r){return new Promise((o,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=u=>{c||(c=true,u?i(u):o());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Ne,"Content-Length":Buffer.byteLength(s)},timeout:r},u=>{u.on("error",l),u.on("end",()=>{let m=u.statusCode??0;l(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),d.write(s),d.end();})}function X(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),r=`${new Date().toISOString()} | ${n} | ${e.message}
2
+ `;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(r)}),appendFileSync(t,r);}catch{}}function He(n){return new Promise(e=>setTimeout(e,n))}function te(n,e){let t=We(n);mkdirSync(t,{recursive:true,mode:448});let r=join(t,`${e.receiptId}.json`);if(existsSync(r))return e.receiptId;let o=`${r}.${process.pid}.tmp`;writeFileSync(o,JSON.stringify(e),{mode:384});try{renameSync(o,r);}catch(i){try{unlinkSync(o);}catch{}if(!existsSync(r))throw i}return e.receiptId}function We(n){return join(w(n),"session-finalize-pending")}var p=emitSemanticControlLog;function M(n){let{projectRoot:e,...t}=n;try{return new O(e).dispatchBoundary(t).snapshot??null}catch(r){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,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:r instanceof Error?r.message:String(r),tool:n.producer}}),null}}var O=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=Ze(e.kind,e.payload??{});if(!t)return {handled:false};let r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=Xe(r,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return o?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(r),new SemanticRuntimeEventProjector).dispatch({definition:o.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${o.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{r.close();}}};function Xe(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,r=e.turnId??t?.canonicalAction?.binding.turnId,o=e.requestId??t?.requestId;if(!r&&!o)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(c=>r?c.turnId===r:c.requestId===o);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.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 Ze(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var ot=512*1024,it=500;var st=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ie(n){let e=n.runtimeStore??new I(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return at(n,e),null;let r=$(n.transcriptPath,t);if(!r.answer){let s=r.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let o=r.fingerprint;if(!o){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=se(r.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId),x(n,s,"satisfied",o);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,o),i.push({obligation:s,violations:a}),x(n,s,"correction_requested",o,a);continue}if(s.correctionFingerprint===o){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved"),x(n,s,"degraded",o,a);}return i.length===0?null:ct(i)}function at(n,e){let t=(e.get(n.sessionId)?.evidenceDegradations??[]).filter(i=>i.contract).slice(-8);if(t.length===0)return;let r=t.map(i=>({obligationId:i.obligationId,contractId:i.contractId,contract:i.contract,promptedAt:i.degradedAt,attempt:i.attempt,correctionRequested:true,violations:[]})),o=$(n.transcriptPath,r);if(!(!o.answer||!o.fingerprint))for(let i of r)se(o.answer,[i]).length>0||e.resolveDegradedEvidence(n.sessionId,i.obligationId)&&x(n,i,"satisfied",o.fingerprint);}function x(n,e,t,r,o=[]){t!=="correction_requested"&&M({projectRoot:n.projectRoot,sessionId:n.sessionId,kind:t==="satisfied"?"verification.succeeded":"verification.failed",payload:{receiptId:e.obligationId,reasonCode:t==="satisfied"?"performance_evidence_satisfied":"performance_evidence_unresolved"},dedupeKey:`${e.obligationId}:${t}:${e.attempt}`,producer:"devflow-evidence-contract"}),p({event:"verification.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:t==="satisfied"?"info":t==="degraded"?"error":"warn",timestamp:Date.now(),data:{stage:"performance_evidence_transition",status:t,contractId:e.contractId,obligationId:e.obligationId,attempt:e.attempt,answerFingerprint:r,violations:o,supersedesDegradation:t==="satisfied"&&e.attempt>0}});}function ct(n){let e=[...new Set(n.flatMap(r=>r.violations))],t=[...new Map(n.map(r=>[r.obligation.contractId,r.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
3
3
 
4
4
  ---
5
5
 
6
6
  `)].join(`
7
7
 
8
- `)}}function se(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=ae(n.split(/\r?\n/)),i=ce(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let l=r.claimLines[c].trim();if(!l||lt(l))continue;let d=i.byLine.get(c);for(let u of gt(l))mt(u,d,a,t);}return [...t]}function ae(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>dt(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function dt(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function lt(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?ut(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function ut(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function mt(n,e,t,o){let r=/\bP0\b/gi;for(let y of n.matchAll(r))re(n,y.index??0,y[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))re(n,y.index??0,y[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))ft(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&o.add("unsupported_benefit_percentage"),d&&!u&&o.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),g=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&h&&!g&&!t&&o.add("raf_without_sampling_evidence");}function re(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=pt(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function pt(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function ft(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function gt(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function $(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,rt),s=Buffer.alloc(i),a=0;for(;a<i;){let g=readSync(t,s,a,i-a,r.size-i+a);if(g===0)break;a+=g;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
- `)+1)));let l=c.split(/\r?\n/).slice(-it),d=e.length>0?Math.min(...e.map(g=>g.promptedAt)):0,u=ht(l,d),h=[...u].reverse().find(g=>yt(g.text,e))??u.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function yt(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=ce(ae(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function P(n){return $(n,[]).answer}function ht(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=It(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,d=typeof l=="string"?l:Array.isArray(l)?l.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
10
- `):"";if(d.trim()){let u=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(u).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:g});}}catch{continue}}return t}function It(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=st.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}var _t={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 F(n){return wt(n)}function wt(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=xt(e,n.artifact);if(Et(t.toState))return t;let o=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return t;let s=o?St(n.artifact,o):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?Rt(n.artifact,o):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function St(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function Rt(n,e){let t=e.canonicalAction,r=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||kt(n)?"action_required":"action_not_required"}function kt(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function xt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,o,r){if(!_t[e.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${o}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:o,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:r,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:o,receiptId:s,reason:r}}),a}function Et(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n,e){let t=join(n,".devflow","delivery-line","state.db");if(!existsSync(t)||!e.trim())return 0;let o;try{o=new DatabaseSync(t,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(e,e),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let l=JSON.parse(a.payload);c=l.evidence?.some(d=>d.metadata?.trust==="external-untrusted")?"untrusted":l.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let l=`session.closed:${a.id}:${e}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(l,a.id,l,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:e,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function le(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Mt(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function jt(n,e=_(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o};try{de(e,s);}catch{}let l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=l.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!r)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Mt(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=jt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var E=1,Ht="memory-snapshot-v1.json",zt=512*1024,fe=256*1024,ge=2e3,Ut=500,Bt=10,Jt=240,Wt=300*1e3,Gt=720*60*60*1e3,Kt=2147483647;function Vt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Yt(n,e={}){let t=S(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(o,Ht)}function Xt(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function L(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&L(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Qt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ye(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=b(e),i=S(r),s=o.generation===void 0?0:o.generation;return o.version!==E||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>fe||!L(o.memoryIds,ge)||!Array.isArray(o.conflicts)||o.conflicts.length>Ut||!o.conflicts.every(Zt)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Wt||!Number.isInteger(s)||s<0||s>Kt||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Qt(o.degradation)?null:{...o,generation:s}}function en(n,e,t,o,r=0){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function tn(n,e={}){let t=e.now??Date.now(),o=Yt(n,e),r;try{r=openSync(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(r);if(!i.isFile()||i.size<=0||i.size>zt)throw new Error("cache_size_invalid");let s=Vt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(r,"utf8")),c=ye(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Gt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:en(n,a?"pending":"degraded",a?"cache_missing":Xt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync(r);}catch{}}}function nn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function on(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=ye(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=fe){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:o.markdown,memoryIds:L(o.memoryIds,ge)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function N(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Jt).join("")}function rn(n){if(n.length===0)return "";let e=n.slice(0,Bt),t=e.map(o=>{let r=N(o.family,"unknown"),i=N(o.entity,"unknown"),s=N(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
8
+ `)}}function se(n,e){let t=new Set,r=new Set(e.flatMap(c=>c.contract.requiredSections)),o=ae(n.split(/\r?\n/)),i=ce(o.headingLines);for(let c of r)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<o.claimLines.length;c++){let l=o.claimLines[c].trim();if(!l||lt(l))continue;let d=i.byLine.get(c);for(let u of gt(l))mt(u,d,a,t);}return [...t]}function ae(n){let e=false,t=[],r=[];for(let o of n){if(/^\s*```/.test(o)){e=!e,t.push(""),r.push(o.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":o.replace(/`[^`]*`/g,"").trim()),r.push(o.replace(/`([^`]*)`/g,(i,s)=>dt(s)?"":s).trim());}return {headingLines:t,claimLines:r}}function dt(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function lt(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?ut(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function ut(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function mt(n,e,t,r){let o=/\bP0\b/gi;for(let y of n.matchAll(o))oe(n,y.index??0,y[0],"p0")||r.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))oe(n,y.index??0,y[0],"high")||r.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))ft(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?r.add("unsupported_confirmed_bottleneck"):r.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&r.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&r.add("unsupported_benefit_percentage"),d&&!u&&r.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),g=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&h&&!g&&!t&&r.add("raf_without_sampling_evidence");}function oe(n,e,t,r){let o=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=pt(o),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:r==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(o)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(o):false}function pt(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,r=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||r.test(n)}function ft(n,e,t){let r=n.slice(Math.max(0,e-40),e),o=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(r)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(r),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(o)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(o);return i||s}function gt(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function $(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let r=lstatSync(n);if(!r.isFile()||r.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let o=fstatSync(t);if(!o.isFile()||o.dev!==r.dev||o.ino!==r.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(o.size,ot),s=Buffer.alloc(i),a=0;for(;a<i;){let g=readSync(t,s,a,i-a,o.size-i+a);if(g===0)break;a+=g;}let c=s.subarray(0,a).toString("utf8");o.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
+ `)+1)));let l=c.split(/\r?\n/).slice(-it),d=e.length>0?Math.min(...e.map(g=>g.promptedAt)):0,u=ht(l,d),h=[...u].reverse().find(g=>yt(g.text,e))??u.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function yt(n,e){let t=new Set(e.flatMap(o=>o.contract.requiredSections)),r=ce(ae(n.split(/\r?\n/u)).headingLines);return [...t].every(o=>r.found.has(o))}function P(n){return $(n,[]).answer}function ht(n,e){let t=[];for(let r=0;r<n.length;r++){let o=n[r];if(o.trim())try{let i=JSON.parse(o),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=It(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,d=typeof l=="string"?l:Array.isArray(l)?l.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
10
+ `):"";if(d.trim()){let u=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${r}:${createHash("sha256").update(o).digest("hex")}`,h=createHash("sha256").update(u).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:g});}}catch{continue}}return t}function It(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,r;for(let o=0;o<n.length;o++){let i=n[o].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=st.find(a=>i===a);s&&(r=s,e.add(s)),t.set(o,r);}return {found:e,byLine:t}}var _t={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 F(n){return wt(n)}function wt(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=xt(e,n.artifact);if(Et(t.toState))return t;let r=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),o=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||o?.source==="explicit_intent";if(!r&&!i)return t;let s=r?St(n.artifact,r):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=r?Rt(n.artifact,r):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function St(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function Rt(n,e){let t=e.canonicalAction,o=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||o?.status==="succeeded"?"action_satisfied":o&&["failed","timeout","unavailable"].includes(o.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||kt(n)?"action_required":"action_not_required"}function kt(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function xt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,r,o){if(!_t[e.toState]?.includes(r))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${r}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${r}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:r,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:o,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:r==="closed"?"info":r.includes("degradation")||r.includes("retry")||r==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:r,receiptId:s,reason:o}}),a}function Et(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n,e){let t=join(n,".devflow","delivery-line","state.db");if(!existsSync(t)||!e.trim())return 0;let r;try{r=new DatabaseSync(t,{timeout:250});let o=r.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(e,e),i=0,s=!!r.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of o){let c="incomplete";try{let l=JSON.parse(a.payload);c=l.evidence?.some(d=>d.metadata?.trust==="external-untrusted")?"untrusted":l.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(r.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let l=`session.closed:${a.id}:${e}`;r.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(l,a.id,l,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:e,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{r?.close();}}function le(n){let e={committed:0,skipped:0,pending:0},t=[];for(let r of n)e[r.status]+=1,r.receiptId&&t.push(r.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Mt(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function jt(n,e=_(),t=true,r,o=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:r};try{de(e,s);}catch{}let l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=l.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:r,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!o)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:r,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Mt(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=jt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var E=1,Ht="memory-snapshot-v1.json",zt=512*1024,fe=256*1024,ge=2e3,Ut=500,Bt=10,Jt=240,Wt=300*1e3,Gt=720*60*60*1e3,Kt=2147483647;function Vt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Yt(n,e={}){let t=S(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(r,Ht)}function Xt(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function L(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&L(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Qt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ye(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=b(e),i=S(o),s=r.generation===void 0?0:r.generation;return r.version!==E||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>fe||!L(r.memoryIds,ge)||!Array.isArray(r.conflicts)||r.conflicts.length>Ut||!r.conflicts.every(Zt)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+Wt||!Number.isInteger(s)||s<0||s>Kt||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!Qt(r.degradation)?null:{...r,generation:s}}function en(n,e,t,r,o=0){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function tn(n,e={}){let t=e.now??Date.now(),r=Yt(n,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>zt)throw new Error("cache_size_invalid");let s=Vt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(o,"utf8")),c=ye(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Gt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:en(n,a?"pending":"degraded",a?"cache_missing":Xt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function nn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function rn(n,e,t){if(!e.trim())return null;try{let r=JSON.parse(e);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=ye(r.snapshot,n,t);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=fe){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:L(r.memoryIds,ge)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function N(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Jt).join("")}function on(n){if(n.length===0)return "";let e=n.slice(0,Bt),t=e.map(r=>{let o=N(r.family,"unknown"),i=N(r.entity,"unknown"),s=N(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
11
11
  ${t.join(`
12
- `)}`}function sn(n){let e=n.now??Date.now();if(nn(n.configPath)===false)return "";let t=on(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:tn(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
13
- DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=rn(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
12
+ `)}`}function sn(n){let e=n.now??Date.now();if(nn(n.configPath)===false)return "";let t=rn(n.projectRoot,n.daemonResponse??"",e),r=t?{snapshot:t,source:"daemon"}:tn(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
13
+ DevFlow memory snapshot=pending; source=${r.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(o.generatedAt).toISOString(),s=o.degradation?.reason?`; reason=${o.degradation.reason}`:"",a=`DevFlow memory snapshot=${o.status}; source=${r.source}; generatedAt=${i}${s}.`,c=on(o.conflicts);return o.markdown?[o.markdown,c,a].filter(Boolean).join(`
14
14
  `):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
15
- `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(sn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function Ie(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function ve(n){let e=ie({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{mn(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(Ie(o)),o&&!r&&ln(t,o.turnId)&&un(P(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?`Call ${projectClaudeToolName("memory_decide_turn")} using the canonical turn ID.`:c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
15
+ `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(sn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function Ie(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function ve(n){let e=ie({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{mn(n.runtimeStore,n.sessionId,t);let r=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),o=r?t.markMemoryTurnStopPrompted(r.turnId):!1,i=[];e&&i.push(e.reason),r&&o&&i.push(Ie(r)),r&&!o&&ln(t,r.turnId)&&un(P(n.transcriptPath))&&i.push(`DevFlow explicit memory ${r.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?`Call ${projectClaudeToolName("memory_decide_turn")} using the canonical turn ID.`:c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
16
16
 
17
- `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function ln(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function un(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function mn(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&r.status==="resolved"))continue;let a=r.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${r.obligationId}\0${r.completedAt}\0${r.attempt}`).digest("hex").slice(0,24)}`:void 0;t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:r.reason,resolvedAt:r.completedAt});}}}async function fn(n,e=_()){let t;try{t=JSON.parse(n);}catch{return null}let o=t.session_id?.trim();if(!o)return null;let r=new I(e),i=ve({projectRoot:e,sessionId:o,transcriptPath:t.transcript_path,stopHookActive:t.stop_hook_active===true,runtimeStore:r});if(i.decision==="block_once")return p({event:"hook.stop.degraded",identity:{projectRoot:e,sessionId:o},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=r.completeExecution(o);if(s?.executionId){let a=openGlobalDevFlowDatabase();try{let c=a.listSessionMemoryTurnsForReconciliation(e,o),l=new Map(a.listLatestTaskIntentArtifacts(e,o).map(d=>[d.turnId,d]));for(let d of c){let u=l.get(d.turnId);!u||d.status==="pending"||F({artifact:u,memoryStatus:d.status,memoryReceiptId:d.receiptId,reason:"stop_obligations_satisfied"});}a.reconcileSkillExecution(s.executionId,"completed",Date.now(),{...le(c),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision}),a.deleteContextReceipt(e,o,s.executionId);}finally{a.close();}}return k(`/api/telemetry/sessions/${encodeURIComponent(o)}/tick`,{timestamp:Date.now()},{fallbackReason:"stop_tick_already_local"}),p({event:"hook.stop.completed",identity:{projectRoot:e,sessionId:o,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}}),null}if(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=await fn(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),4e3).unref();}export{fn as handleStop};
17
+ `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function ln(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function un(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function mn(n,e,t){let r=n.get(e);if(r){for(let o of r.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:e,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:o.contract,runtimeObligationId:o.obligationId},createdAt:o.promptedAt,updatedAt:r.lastActivityAt});for(let o of r.evidenceOutcomes){let i=`evidence:${o.obligationId}`,s=t.getSessionObligation(r.projectRoot,e,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&o.status==="resolved"))continue;let a=o.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${o.obligationId}\0${o.completedAt}\0${o.attempt}`).digest("hex").slice(0,24)}`:void 0;t.resolveSessionObligation({projectRoot:r.projectRoot,sessionId:e,obligationId:i,state:o.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:o.reason,resolvedAt:o.completedAt});}}}async function fn(n,e=_()){let t;try{t=JSON.parse(n);}catch{return null}let r=t.session_id?.trim();if(!r)return null;let o=new I(e),i=ve({projectRoot:e,sessionId:r,transcriptPath:t.transcript_path,stopHookActive:t.stop_hook_active===true,runtimeStore:o});if(i.decision==="block_once")return p({event:"hook.stop.degraded",identity:{projectRoot:e,sessionId:r},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=o.completeExecution(r);if(s?.executionId){let a=openGlobalDevFlowDatabase();try{let c=a.listSessionMemoryTurnsForReconciliation(e,r),l=new Map(a.listLatestTaskIntentArtifacts(e,r).map(d=>[d.turnId,d]));for(let d of c){let u=l.get(d.turnId);!u||d.status==="pending"||F({artifact:u,memoryStatus:d.status,memoryReceiptId:d.receiptId,reason:"stop_obligations_satisfied"});}a.reconcileSkillExecution(s.executionId,"completed",Date.now(),{...le(c),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision}),a.deleteContextReceipt(e,r,s.executionId);}finally{a.close();}}return k(`/api/telemetry/sessions/${encodeURIComponent(r)}/tick`,{timestamp:Date.now()},{fallbackReason:"stop_tick_already_local"}),p({event:"hook.stop.completed",identity:{projectRoot:e,sessionId:r,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}}),null}if(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=await fn(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),4e3).unref();}export{fn as handleStop};
@@ -0,0 +1,15 @@
1
+ # DevFlow Hooks 注册表
2
+
3
+ `hooks.json` 中每个条目的用途说明。Claude Code 的 hooks schema 只接受 `matcher` 与 `hooks` 键,
4
+ `id` / `description` 元数据存放于此,不写入 `hooks.json`(否则 CLI 启动时会产生 unknown keys 警告)。
5
+
6
+ | id | 事件 | 脚本 | 说明 |
7
+ | --- | --- | --- | --- |
8
+ | `session:start:banner` | SessionStart | `session-start` | Compact DevFlow session banner: capability pointer, memory snapshot, gateway status |
9
+ | `pre:devflow-gate` | PreToolUse | `pre-tool-use` | Delivery write gate + execution/context-receipt tracking for Skill and MCP calls. Read-only discovery tools (Read/Grep/Glob/Agent/WebSearch) are deliberately NOT matched — they are advisory only. |
10
+ | `post:telemetry` | PostToolUse | `post-tool-use` | Telemetry completion + memory turn staging (non-blocking observation) |
11
+ | `post:failure-learning` | PostToolUseFailure | `post-tool-use-failure` | Failure classification + learning extraction from failed tool calls |
12
+ | `prompt:intent` | UserPromptSubmit | `user-prompt-submit` | Task intent capture + turn correlation |
13
+ | `stop:finalize` | Stop | `stop` | Memory turn finalize + graceful daemon shutdown |
14
+ | `compact:persist` | PreCompact | `pre-compact` | Persist durable state before context compaction |
15
+ | `session:end:cleanup` | SessionEnd | `session-end` | Lifecycle cleanup: release delivery leases, spool finalize, state cleanup |
@@ -1,20 +1,11 @@
1
- <EXTREMELY_IMPORTANT>
2
- 你正在使用 DevFlow MCP Gateway。
1
+ # DevFlow 能力声明
3
2
 
4
- ## MCP 优先原则
3
+ 你已接入 DevFlow —— 项目智能层:上下文包、符号与依赖检索、项目记忆、知识库和标准工作流。运行 /devflow 查看全部已安装能力,按项目技术栈选择对应领域技能。
5
4
 
6
- 收到 /devflow:* 命令时,必须先调用 SKILL.md 中列出的 MCP 工具。
7
- Hook 会自动拦截不符合规范的原生工具调用,并按提示引导你使用正确的 MCP 工具。
5
+ 使用 /devflow:* 技能时的推荐路径:先调用 SKILL.md 列出的 MCP 工具获取上下文,再基于返回结果分析;需要补充细节时用 Read 读取关联文件。MCP 不可用时重试一次,然后可直接用原生工具检索,并如实说明已降级。
8
6
 
9
- 正确流程:
10
- 1. 调用 Skill 加载命令
11
- 2. 立即调用 MCP 工具
12
- 3. 基于 MCP 结果回答
13
- 4. 如需补充信息,使用 Read 工具读取 MCP 未包含的关联文件
7
+ 真实性约定(无论何时使用 DevFlow 都适用):
14
8
 
15
- 绝对不要:
16
- - 在调用 MCP 之前用 grep/find/Glob/Explore 搜索代码
17
- - 用 WebSearch/WebFetch 替代 get_knowledge
18
- - 用 Agent(Explore) 替代 MCP 工具
19
- - 尝试绕过 Hook 拦截
20
- </EXTREMELY_IMPORTANT>
9
+ - 记忆保存以 DevFlow canonical receipt 为准;队列接受或宿主本地写入不等于保存成功。
10
+ - 静态发现不是运行时测量——不虚构瓶颈、严重度或量化的收益数字。
11
+ - 工作流成功需要 canonical host-action 与验证证据;降级、取消、失败、未知状态不得记为成功。
@@ -9,9 +9,7 @@
9
9
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start\"",
10
10
  "timeout": 15
11
11
  }
12
- ],
13
- "description": "Compact DevFlow session banner: capability pointer, memory snapshot, gateway status",
14
- "id": "session:start:banner"
12
+ ]
15
13
  }
16
14
  ],
17
15
  "PreToolUse": [
@@ -23,9 +21,7 @@
23
21
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-tool-use\"",
24
22
  "timeout": 10
25
23
  }
26
- ],
27
- "description": "Delivery write gate + execution/context-receipt tracking for Skill and MCP calls. Read-only discovery tools (Read/Grep/Glob/Agent/WebSearch) are deliberately NOT matched — they are advisory only.",
28
- "id": "pre:devflow-gate"
24
+ ]
29
25
  }
30
26
  ],
31
27
  "PostToolUse": [
@@ -37,9 +33,7 @@
37
33
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use\"",
38
34
  "timeout": 10
39
35
  }
40
- ],
41
- "description": "Telemetry completion + memory turn staging (non-blocking observation)",
42
- "id": "post:telemetry"
36
+ ]
43
37
  }
44
38
  ],
45
39
  "PostToolUseFailure": [
@@ -51,9 +45,7 @@
51
45
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use-failure\"",
52
46
  "timeout": 10
53
47
  }
54
- ],
55
- "description": "Failure classification + learning extraction from failed tool calls",
56
- "id": "post:failure-learning"
48
+ ]
57
49
  }
58
50
  ],
59
51
  "UserPromptSubmit": [
@@ -65,9 +57,7 @@
65
57
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit\"",
66
58
  "timeout": 5
67
59
  }
68
- ],
69
- "description": "Task intent capture + turn correlation",
70
- "id": "prompt:intent"
60
+ ]
71
61
  }
72
62
  ],
73
63
  "Stop": [
@@ -79,9 +69,7 @@
79
69
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop\"",
80
70
  "timeout": 15
81
71
  }
82
- ],
83
- "description": "Memory turn finalize + graceful daemon shutdown",
84
- "id": "stop:finalize"
72
+ ]
85
73
  }
86
74
  ],
87
75
  "PreCompact": [
@@ -93,9 +81,7 @@
93
81
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-compact\"",
94
82
  "timeout": 15
95
83
  }
96
- ],
97
- "description": "Persist durable state before context compaction",
98
- "id": "compact:persist"
84
+ ]
99
85
  }
100
86
  ],
101
87
  "SessionEnd": [
@@ -107,9 +93,7 @@
107
93
  "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-end\"",
108
94
  "timeout": 15
109
95
  }
110
- ],
111
- "description": "Lifecycle cleanup: release delivery leases, spool finalize, state cleanup",
112
- "id": "session:end:cleanup"
96
+ ]
113
97
  }
114
98
  ]
115
99
  }
@@ -115,17 +115,16 @@ else
115
115
  fi
116
116
  GATEWAY_STATUS="${GATEWAY_STATUS}━━━━━━━━━━━━━━━━━━━━━━━━━━━"
117
117
 
118
- # ── MCP Tool Usage Protocol (injected into every session) ──
118
+ # ── DevFlow capability declaration (injected into every session) ──
119
119
  MCP_PROTOCOL="
120
120
 
121
- ## DevFlow MCP 工具使用协议(必须遵守)
121
+ ## DevFlow MCP 使用指南
122
122
 
123
- 当用户使用 /devflow: 开头的技能时(如 /devflow:react、/devflow:vue、/devflow:context 等),你必须按以下流程操作:
123
+ 用户使用 /devflow: 技能时(如 /devflow:react、/devflow:vue、/devflow:context),推荐流程:
124
124
 
125
- ### Step 1: 获取上下文(必须先执行)
125
+ ### Step 1: 获取上下文
126
126
  调用 mcp__plugin_devflow_devflow__get_project_context,参数格式:{\"query\": \"用户的问题描述\", \"projectRoot\": \"\${CLAUDE_PROJECT_DIR}\"}
127
- 这个工具返回项目中的相关文件、符号、风险提示和下一步建议。
128
- 不要跳过这一步。不要用 Explore、Agent、Grep 或 Bash 代替。
127
+ 返回相关文件、符号、风险提示与下一步建议——通常比自行搜索更快更准。
129
128
 
130
129
  ### Step 2: 按需调用领域工具
131
130
  根据已加载 Skill 和 command registry 调用对应的 MCP 工具。以下仅为高频示例,完整能力以 /devflow 列表和 command registry 为准:
@@ -140,21 +139,21 @@ MCP_PROTOCOL="
140
139
  ### Step 3: 基于工具返回结果进行分析
141
140
  用 Read 确认工具返回的关键文件,然后给出分析结论。
142
141
 
143
- ### 铁律
144
- - 永远不要用 Explore、Agent、Grep 或 Glob 替代 MCP 工具的第一步上下文获取
142
+ ### 约定
145
143
  - Every mcp__plugin_devflow_devflow__ tool MUST pass projectRoot = \${CLAUDE_PROJECT_DIR}; missing projectRoot is rejected; no cwd fallback.
146
- - 如果 MCP 工具返回错误,重试一次;再失败则回退到直接读文件"
144
+ - MCP 工具失败时重试一次;再失败则回退直接读文件,并如实说明已降级"
147
145
 
148
146
  COMPACT_PROTOCOL="
149
147
 
150
- ## DevFlow compact protocol
151
- - Project: ${PROJECT_NAME} (${PROJECT_ROOT})
152
- - For /devflow:* tasks, call mcp__plugin_devflow_devflow__get_project_context before broad native search, then use the applicable domain MCP tool.
153
- - Explicit memory is successful only after a DevFlow canonical receipt. Queue acceptance or host-local memory is not a successful save.
148
+ ## DevFlow
149
+ You have DevFlow — project intelligence for this repo: scoped context packs, symbol and dependency search, project memory, knowledge base, and standardized workflows. /devflow lists every installed capability; /devflow:<stack> skills pair a task with the right tool. mcp__plugin_devflow_devflow__get_project_context is the fastest way to scope a task before searching.
150
+
151
+ How DevFlow reports truth (whenever you use it):
152
+ - A memory save counts only with a DevFlow canonical receipt; queue acceptance or host-local memory is not a saved memory.
154
153
  - Static findings are not runtime measurements. Do not claim observed bottlenecks, severity, or quantified benefit without evidence.
155
154
  - Workflow success requires canonical host-action and verification evidence. Never convert degraded, cancelled, failed, or unknown state into success.
156
155
  - Full versioned rules: devflow://protocol/core, devflow://protocol/memory, devflow://protocol/evidence.
157
- - Retry MCP transport failure once, then degrade truthfully to direct file inspection."
156
+ - If an MCP call fails, retry once, then fall back to direct file inspection and say so."
158
157
 
159
158
  DEVFLOW_DAEMON_REACHABLE=0
160
159
  DEVFLOW_DAEMON_LAUNCHING=0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.18.73",
3
+ "version": "0.19.2",
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.73",
16
- "@devflow-tools/context-engine": "0.18.73",
17
- "@devflow-tools/database": "0.18.73",
18
- "@devflow-tools/mcp-server": "0.18.73",
19
- "@devflow-tools/memory-engine": "0.18.73",
20
- "@devflow-tools/sdk": "0.18.73",
21
- "@devflow-tools/semantic-engine": "0.18.73",
22
- "@devflow-tools/server": "0.18.73",
23
- "@devflow-tools/task-runtime": "0.18.73",
24
- "@devflow-tools/telemetry": "0.18.73",
25
- "@devflow-tools/workflow-engine": "0.18.73"
15
+ "@devflow-tools/benchmark": "0.19.2",
16
+ "@devflow-tools/context-engine": "0.19.2",
17
+ "@devflow-tools/database": "0.19.2",
18
+ "@devflow-tools/mcp-server": "0.19.2",
19
+ "@devflow-tools/memory-engine": "0.19.2",
20
+ "@devflow-tools/sdk": "0.19.2",
21
+ "@devflow-tools/semantic-engine": "0.19.2",
22
+ "@devflow-tools/server": "0.19.2",
23
+ "@devflow-tools/task-runtime": "0.19.2",
24
+ "@devflow-tools/telemetry": "0.19.2",
25
+ "@devflow-tools/workflow-engine": "0.19.2"
26
26
  },
27
27
  "devDependencies": {
28
- "@devflow-tools/devflow": "0.18.65"
28
+ "@devflow-tools/devflow": "0.19.2"
29
29
  },
30
30
  "allowScripts": {
31
31
  "better-sqlite3@12.11.1": true,
@@ -50,7 +50,7 @@
50
50
  "hooks",
51
51
  "skills"
52
52
  ],
53
- "gitHead": "f80c5d8fde0b5387e89cf3d38a0c533a5fbfb8c2",
53
+ "gitHead": "98ce356672b913045d8435cabd6ae68233f5723e",
54
54
  "license": "MIT",
55
55
  "repository": {
56
56
  "type": "git",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/cli",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "devflow": "./bin/devflow.cjs"
@@ -14,33 +14,33 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@colbymchenry/codegraph": "^1.1.1",
17
- "@devflow-tools/adapters": "0.19.0",
18
- "@devflow-tools/benchmark": "0.19.0",
19
- "@devflow-tools/context-engine": "0.19.0",
20
- "@devflow-tools/database": "0.19.0",
21
- "@devflow-tools/delivery-line": "0.19.0",
22
- "@devflow-tools/devflow": "0.19.0",
23
- "@devflow-tools/knowledge-engine": "0.19.0",
24
- "@devflow-tools/mcp-server": "0.19.0",
25
- "@devflow-tools/memory-engine": "0.19.0",
26
- "@devflow-tools/plugin-animation": "0.19.0",
27
- "@devflow-tools/plugin-css": "0.19.0",
28
- "@devflow-tools/plugin-docker": "0.19.0",
29
- "@devflow-tools/plugin-electron": "0.19.0",
30
- "@devflow-tools/plugin-git": "0.19.0",
31
- "@devflow-tools/plugin-graphql": "0.19.0",
32
- "@devflow-tools/plugin-nest": "0.19.0",
33
- "@devflow-tools/plugin-nextjs": "0.19.0",
34
- "@devflow-tools/plugin-performance": "0.19.0",
35
- "@devflow-tools/plugin-react": "0.19.0",
36
- "@devflow-tools/plugin-tailwind": "0.19.0",
37
- "@devflow-tools/plugin-taro": "0.19.0",
38
- "@devflow-tools/plugin-ui-layout": "0.19.0",
39
- "@devflow-tools/plugin-vue": "0.19.0",
40
- "@devflow-tools/sdk": "0.19.0",
41
- "@devflow-tools/server": "0.19.0",
42
- "@devflow-tools/telemetry": "0.19.0",
43
- "@devflow-tools/workflow-engine": "0.19.0",
17
+ "@devflow-tools/adapters": "0.19.2",
18
+ "@devflow-tools/benchmark": "0.19.2",
19
+ "@devflow-tools/context-engine": "0.19.2",
20
+ "@devflow-tools/database": "0.19.2",
21
+ "@devflow-tools/delivery-line": "0.19.2",
22
+ "@devflow-tools/devflow": "0.19.2",
23
+ "@devflow-tools/knowledge-engine": "0.19.2",
24
+ "@devflow-tools/mcp-server": "0.19.2",
25
+ "@devflow-tools/memory-engine": "0.19.2",
26
+ "@devflow-tools/plugin-animation": "0.19.2",
27
+ "@devflow-tools/plugin-css": "0.19.2",
28
+ "@devflow-tools/plugin-docker": "0.19.2",
29
+ "@devflow-tools/plugin-electron": "0.19.2",
30
+ "@devflow-tools/plugin-git": "0.19.2",
31
+ "@devflow-tools/plugin-graphql": "0.19.2",
32
+ "@devflow-tools/plugin-nest": "0.19.2",
33
+ "@devflow-tools/plugin-nextjs": "0.19.2",
34
+ "@devflow-tools/plugin-performance": "0.19.2",
35
+ "@devflow-tools/plugin-react": "0.19.2",
36
+ "@devflow-tools/plugin-tailwind": "0.19.2",
37
+ "@devflow-tools/plugin-taro": "0.19.2",
38
+ "@devflow-tools/plugin-ui-layout": "0.19.2",
39
+ "@devflow-tools/plugin-vue": "0.19.2",
40
+ "@devflow-tools/sdk": "0.19.2",
41
+ "@devflow-tools/server": "0.19.2",
42
+ "@devflow-tools/telemetry": "0.19.2",
43
+ "@devflow-tools/workflow-engine": "0.19.2",
44
44
  "@inquirer/prompts": "^7.10.1",
45
45
  "chalk": "^5.3.0",
46
46
  "commander": "^12.0.0"
@@ -53,7 +53,7 @@
53
53
  "dist",
54
54
  "bin"
55
55
  ],
56
- "gitHead": "d4f681428ac2f83d868e152a10c85ec892afda8b",
56
+ "gitHead": "3b0b20607162ab93415b204c0bfb46c15df328b2",
57
57
  "description": "Command-line interface for DevFlow development intelligence and diagnostics.",
58
58
  "license": "MIT",
59
59
  "repository": {