@devflow-tools/claude-code-plugin 0.18.62 → 0.18.64

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,7 +1,7 @@
1
1
  {
2
2
  "name": "devflow",
3
3
  "description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
4
- "version": "0.18.62",
4
+ "version": "0.18.64",
5
5
  "author": {
6
6
  "name": "DevFlow"
7
7
  },
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "blockedNative": [],
10
10
  "source": "core",
11
- "sourceVersion": "0.18.62",
11
+ "sourceVersion": "0.18.64",
12
12
  "requiresContext": false,
13
13
  "evidenceMode": "runtime",
14
14
  "skillPath": "skills/devflow:doctor/SKILL.md",
@@ -35,7 +35,7 @@
35
35
  "WebFetch"
36
36
  ],
37
37
  "source": "core",
38
- "sourceVersion": "0.18.62",
38
+ "sourceVersion": "0.18.64",
39
39
  "requiresContext": true,
40
40
  "evidenceMode": "mixed",
41
41
  "skillPath": "skills/devflow:context/SKILL.md",
@@ -60,7 +60,7 @@
60
60
  "Explore"
61
61
  ],
62
62
  "source": "core",
63
- "sourceVersion": "0.18.62",
63
+ "sourceVersion": "0.18.64",
64
64
  "requiresContext": true,
65
65
  "evidenceMode": "mixed",
66
66
  "skillPath": "skills/devflow:graph/SKILL.md",
@@ -79,7 +79,7 @@
79
79
  "WebFetch"
80
80
  ],
81
81
  "source": "core",
82
- "sourceVersion": "0.18.62",
82
+ "sourceVersion": "0.18.64",
83
83
  "requiresContext": true,
84
84
  "evidenceMode": "mixed",
85
85
  "skillPath": "skills/devflow:knowledge/SKILL.md",
@@ -103,7 +103,7 @@
103
103
  "Explore"
104
104
  ],
105
105
  "source": "core",
106
- "sourceVersion": "0.18.62",
106
+ "sourceVersion": "0.18.64",
107
107
  "requiresContext": true,
108
108
  "evidenceMode": "mixed",
109
109
  "skillPath": "skills/devflow:memory/SKILL.md",
@@ -119,7 +119,7 @@
119
119
  ],
120
120
  "blockedNative": [],
121
121
  "source": "core",
122
- "sourceVersion": "0.18.62",
122
+ "sourceVersion": "0.18.64",
123
123
  "requiresContext": true,
124
124
  "evidenceMode": "mixed",
125
125
  "skillPath": "skills/devflow:workflow/SKILL.md",
@@ -149,11 +149,12 @@
149
149
  "delivery_retry_task",
150
150
  "delivery_import_external_change",
151
151
  "delivery_export",
152
- "delivery_cancel"
152
+ "delivery_cancel",
153
+ "delivery_rebind_session"
153
154
  ],
154
155
  "blockedNative": [],
155
156
  "source": "core",
156
- "sourceVersion": "0.18.62",
157
+ "sourceVersion": "0.18.64",
157
158
  "requiresContext": true,
158
159
  "evidenceMode": "mixed",
159
160
  "skillPath": "skills/devflow:delivery/SKILL.md",
@@ -177,7 +178,8 @@
177
178
  "mcp__plugin_devflow_devflow__delivery_retry_task",
178
179
  "mcp__plugin_devflow_devflow__delivery_import_external_change",
179
180
  "mcp__plugin_devflow_devflow__delivery_export",
180
- "mcp__plugin_devflow_devflow__delivery_cancel"
181
+ "mcp__plugin_devflow_devflow__delivery_cancel",
182
+ "mcp__plugin_devflow_devflow__delivery_rebind_session"
181
183
  ]
182
184
  }
183
185
  },
@@ -14,7 +14,7 @@ import {createServer,createConnection}from'net';import {createHash,randomUUID as
14
14
  `)+1)));let d=c.split(/\r?\n/).slice(-xa),u=t.length>0?Math.min(...t.map(p=>p.promptedAt)):0,l=Wa(d,u),f=[...l].reverse().find(p=>qa(p.text,t))??l.at(-1);return f?.text?{answer:f.text,fingerprint:f.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{n!==void 0&&closeSync$1(n);}}function qa(e,t){let n=new Set(t.flatMap(r=>r.contract.requiredSections)),o=jo(Po(e.split(/\r?\n/u)).headingLines);return [...n].every(r=>o.found.has(r))}function ze(e){return Tt(e,[]).answer}function Wa(e,t){let n=[];for(let o=0;o<e.length;o++){let r=e[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=Ua(i.timestamp);if(c>0&&c+5e3<t)continue;let d=s.content,u=typeof d=="string"?d:Array.isArray(d)?d.filter(l=>l&&typeof l=="object"&&l.type==="text").map(l=>l.text).filter(l=>typeof l=="string").join(`
15
15
  `):"";if(u.trim()){let l=u.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,f=createHash("sha256").update(l).digest("hex"),p=createHash("sha256").update(`${m}\0${f}`).digest("hex");n.push({text:l,timestamp:c,fingerprint:p});}}catch{continue}}return n}function Ua(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="string")return 0;let t=Date.parse(e);return Number.isFinite(t)?t:0}function jo(e){let t=new Set,n=new Map,o;for(let r=0;r<e.length;r++){let i=e[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=ge.find(a=>i===a);s&&(o=s,t.add(s)),n.set(r,o);}return {found:t,byLine:n}}function Ho(e){let t;try{if(Ya(e.toolResponse))return null;t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let n=t.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId);if(!n)return null;let o=Ba(e.toolInput);if(o.length===0)return null;let r=e.toolName==="Read"?Ka(e.toolInput):void 0,i=r?n.selectedFiles?.find(u=>Ja(e.projectRoot,u,r)):void 0,s=Ga(e.toolName),a=i?"code":n.canonicalNextAction===s?"action":null,c=i&&o.includes(i)?i:a==="action"&&o.includes(s)?s:void 0;if(a&&c){let u=[n.contextHash,n.requestId??"",a,c,e.toolUseId??`${e.sessionId}:${e.executionId??n.executionId}`].join("\0");t.recordContextSelectionEvent({id:`ctxsel:${createHash("sha256").update(u).digest("hex").slice(0,32)}`,projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId,selectionType:a,candidateId:c,toolName:e.toolName,toolUseId:e.toolUseId,selectedAt:Date.now()});}let d=t.listRetrievalLedgerEvents({projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId}).filter(u=>u.stage==="selected"&&o.includes(u.sourceId));for(let u of d)t.appendRetrievalLedgerEvent({...u,id:retrievalLedgerTransitionId(u.id,"consumed",e.toolUseId??e.toolName),stage:"consumed",toolEvidence:[e.toolUseId??e.toolName],evidenceIds:o,actor:e.toolName,reasonCode:"structural_evidence_ref",payload:{...u.payload,consumedByTool:e.toolName},createdAt:Date.now()});return d.length>0&&he({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n.executionId,requestId:n.requestId,contextReceipt:n.contextHash},level:"info",timestamp:Date.now(),data:{stage:"consumed",actor:e.toolName,consumedCount:d.length,evidenceRefCount:o.length}}),a}catch(n){throw he({event:"hook.runtime.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:"warn",timestamp:Date.now(),data:{stage:"retrieval_attribution",actor:e.toolName,reason:n instanceof Error?n.message:String(n)}}),n}finally{try{t?.close();}catch{}}}function No(e){let t=openGlobalDevFlowDatabase();try{let n=t.listRetrievalLedgerEvents(e),o=new Map(n.filter(l=>l.stage==="selected").map(l=>[$o(l),l])),r=new Map(n.filter(l=>l.stage==="consumed").map(l=>[$o(l),l])),i=0,s=0,a=0;for(let[l,m]of o){let f=r.get(l);f&&e.verificationReceipt&&t.appendRetrievalLedgerEvent({...f,id:retrievalLedgerTransitionId(f.id,"verified",e.verificationReceipt),stage:"verified",verificationReceipt:e.verificationReceipt,reasonCode:"same_task_verification_receipt",createdAt:e.finishedAt??Date.now()});let p=f&&e.verificationReceipt&&e.outcome!=="unknown"?e.outcome:"unknown",g=p==="positive"?"positive_outcome":p==="negative"?"negative_outcome":"unknown_outcome";t.appendRetrievalLedgerEvent({...m,id:retrievalLedgerTransitionId(m.id,g,e.verificationReceipt??e.sessionId),stage:g,reason:f?e.outcomeReason:"selected_not_consumed",toolEvidence:f?.toolEvidence??[],verificationReceipt:p==="unknown"?void 0:e.verificationReceipt,payload:{...m.payload,consumed:!!f},createdAt:e.finishedAt??Date.now()}),g==="positive_outcome"?i+=1:g==="negative_outcome"?s+=1:a+=1;}let c=e.requiredChannels.map(l=>{let m=[...o.values()].filter(p=>p.sourceType===l).length,f=[...r.values()].filter(p=>p.sourceType===l).length;return {channel:l,selected:m,consumed:f,verified:e.verificationReceipt?f:0}}),d={status:c.length>0&&c.every(l=>l.selected>0&&l.consumed===l.selected&&l.verified===l.selected)?"complete":"unavailable",channels:c},u={consumed:r.size,positive:i,negative:s,unknown:a,consumedSources:[...r.values()].map(l=>({sourceType:l.sourceType,sourceId:l.sourceId})),proof:d};return e.verificationReceipt&&r.size>0&&he({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:"info",timestamp:e.finishedAt??Date.now(),data:{stage:"verified",verifiedCount:r.size}}),he({event:"task.proof.completed",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:d.status==="complete"?"info":"warn",timestamp:e.finishedAt??Date.now(),data:d}),he({event:"retrieval.attribution.transitioned",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:e.executionId,requestId:e.requestId},level:a>0?"warn":"info",timestamp:e.finishedAt??Date.now(),data:{stage:"session_outcome",selectedCount:o.size,consumedCount:r.size,verifiedCount:e.verificationReceipt?r.size:0,positiveCount:i,negativeCount:s,unknownCount:a}}),u}finally{t.close();}}function Ba(...e){let t=new Set,n=(o,r=0)=>{if(!(r>6||o==null)){if(typeof o=="string"){try{n(JSON.parse(o),r+1);}catch{}return}if(Array.isArray(o)){for(let i of o)n(i,r+1);return}if(typeof o=="object")for(let[i,s]of Object.entries(o))if((i==="evidenceRefs"||i==="_devflow_evidence_refs")&&Array.isArray(s))for(let a of s)typeof a=="string"&&a.trim()&&t.add(a.trim());else n(s,r+1);}};for(let o of e)n(o);return [...t]}function Ka(e){for(let t of ["file_path","path"]){let n=e[t];if(typeof n=="string"&&n.trim())return n.trim()}}function Ja(e,t,n){let o=resolve(e,t),r=isAbsolute(n)?resolve(n):resolve(e,n);return o===r}function Ga(e){return e.startsWith("mcp__")?e.split("__").at(-1)??e:e}function Ya(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return t.ok===false||t.success===false||t.isError===true||!!t.error||["failed","rejected","unavailable"].includes(String(t.status??""))}function $o(e){return [e.requestId,e.contextReceipt,e.sourceType,e.sourceId].join("\0")}function he(e){try{I(e);}catch{}}var rc=8*1024*1024;function Wo(e){if(!e.transcriptPath||!existsSync(e.transcriptPath))return {status:"unavailable",eventsRead:0,failuresFound:0,failuresRecorded:0,reason:"transcript_path_unavailable"};let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=t.getLatestTranscriptCheckpoint({projectRoot:e.projectRoot,hostId:"claude-code",sessionId:e.sessionId,sourcePath:e.transcriptPath}),o=statSync(e.transcriptPath).size,r=Math.min(n?.byteOffset??0,o),i=Math.min(rc,o-r);if(i<=0)return {status:"completed",eventsRead:0,failuresFound:0,failuresRecorded:0,checkpointId:n?.id};let s=Buffer.alloc(i),a=openSync$1(e.transcriptPath,"r");try{readSync(a,s,0,i,r);}finally{closeSync$1(a);}let c=s.toString("utf8").split(/\r?\n/u).filter(Boolean),d=t.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId),u=new Map,l=new Set,m=0,f=0;for(let y of c){let R;try{R=JSON.parse(y);}catch{continue}for(let b of Ct(R,u)){let _=claudeCodeRuntimeAdapter.normalizeToolResult(b,{projectRoot:e.projectRoot});if(_.success||!_.error)continue;let A=_.toolUseId??_.sourceHash;if(l.has(A))continue;l.add(A),m++;let x=_.toolUseId?t.getToolCallEventByToolUseId(e.sessionId,_.toolUseId):null,D=qo(x?.input,"_devflow_turn_id"),P=qo(x?.input,"_devflow_request_id"),M=D?d.find(S=>S.turnId===D):[...d].reverse().find(S=>(!x?.executionId||S.executionId===x.executionId)&&S.createdAt<=(x?.timestamp??_.timestamp))??d.at(-1),E=`host-failure:${_.sourceHash}`;t.insertEvent({kind:"host_transcript_tool_failure",timestamp:_.timestamp,success:!1,toolName:_.canonicalName??_.requestedName,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:D??M?.turnId,requestId:P??M?.requestId,sourceId:E,toolUseId:_.toolUseId,correlatedEventId:x?.eventId,requestedName:_.requestedName,canonicalName:_.canonicalName,failureCategory:_.failureCategory,error:_.error.slice(0,1e3)}}),I({event:"host.tool.result.reconciled",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,turnId:D??M?.turnId,requestId:P??M?.requestId,executionId:x?.executionId},level:"warn",timestamp:Date.now(),data:{toolUseId:_.toolUseId,toolName:_.canonicalName??_.requestedName,failureCategory:_.failureCategory,correlation:x?"tool_use_id":"timestamp_fallback"}}),f++;}}let p=createHash("sha256").update(s).digest("hex"),g=`transcript:${createHash("sha256").update(`${e.projectRoot}\0${e.sessionId}\0${e.transcriptPath}\0${r+i}\0${p}`).digest("hex").slice(0,24)}`;return t.appendTranscriptCheckpoint({id:g,projectRoot:e.projectRoot,hostId:"claude-code",sessionId:e.sessionId,sourcePath:e.transcriptPath,sourceHash:p,byteOffset:r+i,eventCount:c.length,createdAt:Date.now()}),I({event:"session.reconciled",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId},level:m>0?"warn":"info",timestamp:Date.now(),data:{stage:"transcript",eventsRead:c.length,failuresFound:m,failuresRecorded:f,checkpointId:g}}),{status:"completed",eventsRead:c.length,failuresFound:m,failuresRecorded:f,checkpointId:g}}catch(n){return {status:"degraded",eventsRead:0,failuresFound:0,failuresRecorded:0,reason:n instanceof Error?n.message:String(n)}}finally{t.close();}}function qo(e,t){let n=e?.[t];return typeof n=="string"&&n.trim()?n.trim():void 0}function Ct(e,t,n=0){if(n>7||e===null||e===void 0)return [];if(Array.isArray(e))return e.flatMap(s=>Ct(s,t,n+1));if(typeof e!="object")return [];let o=e,r=typeof o.type=="string"?o.type:"";r==="tool_use"&&typeof o.id=="string"&&typeof o.name=="string"&&t.set(o.id,o.name);let i=[];if(r==="tool_result"){let s=typeof o.tool_use_id=="string"?o.tool_use_id:void 0;i.push({tool_name:s?t.get(s)??"unknown":"unknown",tool_use_id:s,tool_response:o.content,is_error:o.is_error===true,...o.is_error===true?{error:Mt(o.content)||"host tool result failed"}:{},timestamp:o.timestamp});}else (o.tool_name||o.toolName)&&(o.tool_response!==void 0||o.output!==void 0||o.error!==void 0)&&i.push(o);for(let[s,a]of Object.entries(o))s==="content"&&r==="tool_result"||i.push(...Ct(a,t,n+1));return i}function Mt(e){if(typeof e=="string")return e.slice(0,4e3);if(Array.isArray(e))return e.map(Mt).filter(Boolean).join(`
16
16
  `).slice(0,4e3);if(!e||typeof e!="object")return "";let t=e;return [t.text,t.content,t.message].map(Mt).filter(Boolean).join(`
17
- `).slice(0,4e3)}var ac={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 Uo(e){return cc(e)}function cc(e){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=mc(t,e.artifact);if(pc(n.toState))return n;let o=t.getContextReceiptForRequest(e.artifact.projectRoot,e.artifact.sessionId,e.artifact.requestId),r=t.getMemoryTurn(e.artifact.turnId),i=e.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return n;let s=o?dc(e.artifact,o):"context_ready";n.toState==="intent_bound"&&(n=F(t,n,e,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?lc(e.artifact,o):"action_not_required";if((n.toState==="context_ready"||n.toState==="context_degraded")&&(a==="action_not_required"?n=F(t,n,e,"action_not_required","task_action_not_required"):n=F(t,n,e,"action_required","canonical_action_obligation_present")),n.toState==="action_required"){if(a==="action_required")return n;if(a==="action_failed")return F(t,n,e,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?n=F(t,n,e,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(n=F(t,n,e,"action_satisfied","canonical_action_succeeded"));}if(n.toState==="action_failed")if(a==="action_satisfied")n=F(t,n,e,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")n=F(t,n,e,"action_degraded","canonical_action_retry_degraded");else return n;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(n.toState)&&(n=F(t,n,e,e.memoryStatus==="pending"?"memory_quarantined":"memory_decided",e.memoryStatus==="pending"?e.reason:`canonical_memory_${e.memoryStatus}`)),n.toState==="memory_decided"?F(t,n,e,c?"closed_with_degradation":"closed",e.reason):n.toState==="memory_quarantined"?F(t,n,e,e.retryOwned?"closed_with_retry_work":"closed_with_degradation",e.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):n}finally{t.close();}}function dc(e,t){return e.intent==="memory"||e.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function lc(e,t){let n=t.canonicalAction,r=(n?(t.actionAttempts??[]).filter(i=>i.tool===n.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||n?.status==="degraded"||n?.status==="unsupported"?"action_degraded":n?.required||uc(e)?"action_required":"action_not_required"}function uc(e){return ["create","modify","debug","test","format"].includes(e.action)||["feature","refactor","performance"].includes(e.intent)}function mc(e,t){let n=e.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!n)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return n}function F(e,t,n,o,r){if(!ac[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash("sha256").update(`${n.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=e.appendTerminalTransition({projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,executionId:n.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:n.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:n.memoryStatus,retryOwned:n.retryOwned??false,sourceIntentHash:n.artifact.artifactHash},createdAt:Date.now()});return I({event:"terminal.state.transitioned",identity:{projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,...n.artifact.executionId?{executionId:n.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:t.toState,nextState:o,receiptId:s,reason:r}}),a}function pc(e){return e==="closed"||e==="closed_with_degradation"||e==="closed_with_retry_work"}var fc=new Set(["delivered","cancelled","rejected"]),gc=new Set(["cancelled","rejected"]),yc=new Set(["Write","Edit","NotebookEdit","Bash"]);function hc(e,t){if(e!=="Bash"||typeof t?.command!="string")return false;let o="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${o}(?: \\|\\| ${o})*$`,"u").test(t.command)}function Ko(e,t){let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n)||!t.trim())return 0;let o;try{o=new DatabaseSync(n,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(t,t),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let d=JSON.parse(a.payload);c=d.evidence?.some(u=>u.metadata?.trust==="external-untrusted")?"untrusted":d.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let d=`session.closed:${a.id}:${t}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(d,a.id,d,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:t,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function Jo(e,t,n,o,r){if(!yc.has(n)||!t.trim()||hc(n,r))return null;let i=join(e,".devflow","delivery-line","state.db");if(!existsSync(i))return null;let s;try{s=new DatabaseSync(i,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let p of f){let g=[];try{g=JSON.parse(p.aliases);}catch{}(p.source_path===e||g.includes(e))&&c.add(p.case_id);}}let u=[];for(let f of a){let p=JSON.parse(f.payload),g=c.has(f.id);(p.sessionId===t||t===f.id||g)&&u.push({id:f.id,payload:p,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof p.updatedAt=="number"?p.updatedAt:0});let y=typeof p.stage=="string"?p.stage:"unknown";if(!fc.has(y)){if(o&&y==="executing"){let R=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),b=typeof p.sessionId=="string"?p.sessionId:void 0,_=typeof p.executionId=="string"?p.executionId:void 0,A=o===R?.id||o===R?.lease_owner||o===_,x=t===f.id||t===b;if(R?.id&&A&&x)return null}if(p.sessionId===t||t===f.id||g)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:y,message:`Delivery case ${f.id} is ${y}; use the Delivery task lease before modifying files.`}}}let l=u.sort((f,p)=>p.updatedAt-f.updatedAt)[0],m=typeof l?.payload.stage=="string"?l.payload.stage:void 0;return l&&m&&gc.has(m)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:l.id,stage:m,message:`Delivery case ${l.id} is ${m}; start a new Delivery case or session before modifying files.`}:null}catch{return {code:"DELIVERY_AUTHORITY_UNAVAILABLE",caseId:"unknown",stage:"unknown",message:"Delivery state cannot be read; file writes are blocked until runtime health is restored."}}finally{s?.close();}}function Ot(e){let t={committed:0,skipped:0,pending:0},n=[];for(let o of e)t[o.status]+=1,o.receiptId&&n.push(o.receiptId);return {memoryReceiptIds:[...new Set(n)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function H(e){return (e instanceof Error?e.message:String(e)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var G=class extends Error{constructor(t,n){super(`session_finalize_${t}:${n}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function ve(e){let t;try{t=openGlobalDevFlowDatabase();let n=(e.executionId?t.getSkillExecution(e.executionId):null)??t.getLatestSkillExecutionForSession(e.sessionId),o={stage:e.stage,reason:e.reason,degradedAt:Date.now()};n&&t.mergeSkillExecutionMetadata(n.executionId,{...e.metadata,sessionFinalizationDegradations:[o]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId,...o}}),I({event:"hook.session_end.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId},level:"warn",timestamp:o.degradedAt,data:{stage:e.stage,reason:e.reason}});}catch{}finally{t?.close();}}function Ve(e,t=Ce(),n=true,o,r=true){let i;try{i=JSON.parse(e);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:e,sessionId:s,cleanupSharedState:n,executionId:o};try{Ko(t,s);}catch{}let d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let u=d.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),l=d.getWorkByIdempotencyKey(a),m={status:u.state==="closed"||u.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:l?.state??"pending",closureState:u.state,pendingWorkCount:u.pendingWorkCount,...l?.id?{workItemId:l.id}:{}};return I({event:"hook.session_end.completed",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(u){if(!r)throw u;return bo(t,{receiptId:a,...c}),I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:H(u),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}async function Yo(e,t=Ce(),n=true,o){let r;try{r=JSON.parse(e);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new N(t),a=s.get(i),c=Wo({projectRoot:t,sessionId:i,transcriptPath:r.transcript_path}),d={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(p=>p.contractId)??[],transcriptReconciliation:c},u=o?.telemetry??new ee,l=!o?.telemetry,m=false,f;try{try{await u.flushAndAggregate();}catch{}let p=Date.now(),g=o?.executionId??a?.executionId,y;try{let v=openGlobalDevFlowDatabase();try{y=v.listSessionMemoryTurnsForReconciliation(t,i);for(let h of y){let k=`memory:${h.turnId}`,w=v.getSessionObligation(t,i,k);w?w.state==="open"&&h.status!=="pending"&&v.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:k,state:"satisfied",receiptId:h.receiptId,reason:h.reason,resolvedAt:h.decidedAt}):v.upsertSessionObligation({obligationId:k,projectRoot:t,sessionId:i,turnId:h.turnId,kind:"memory_decision",state:h.status==="pending"?"open":"satisfied",payload:{eventId:h.eventId,promptHash:h.promptHash},receiptId:h.receiptId,reason:h.reason,createdAt:h.createdAt,updatedAt:h.decidedAt??h.createdAt,resolvedAt:h.decidedAt});}}finally{v.close();}}catch(v){let h=H(v),k={...d,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:h,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"turn_load",reason:h,metadata:k}),new G("turn_load",h)}let R=Ot(y),b=o?.memory??(f=new MemoryGate(t)),_={status:"completed"};try{_=typeof b.reconcileTurnObservationLineage=="function"?{status:"completed",...await b.reconcileTurnObservationLineage(y)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(v){let h=H(v);throw _={status:"degraded",reason:h},ve({projectRoot:t,sessionId:i,executionId:g,stage:"memory_lineage",reason:h,metadata:{...R,...d,memoryLineageReconciliation:_}}),new G("memory_lineage",h)}let A={status:"unknown",selected:0,consumed:0,unknown:0,positive:0,negative:0};try{let v=ze(r.transcript_path),h=openGlobalDevFlowDatabase(),k="unknown",w="no_terminal_host_action_evidence",ue,L,q,X=[],lt=[];try{let V=h.listHostActionsForSession(t,i,g),En=V.filter(O=>O.state==="verified"),ut=V.filter(O=>["failed","cancelled","degraded"].includes(O.state));ut.length>0?(k="negative",w=`terminal_host_action_${ut[0].state}`):En.length>0&&(k="positive",w="host_action_verified");let Te=ut[0]??En.at(-1);if(ue=Te?.runId,L=Te?.contextReceipt,q=Te?.evidenceHash,lt=V.flatMap(O=>{let Q=O.report.toolUseIds;return Array.isArray(Q)?Q.filter(me=>typeof me=="string"):[]}),!Te&&g){let O=h.getSkillExecution(g),Q=O?.metadata&&typeof O.metadata=="object"&&Array.isArray(O.metadata.policyVerificationOutcomes)?O.metadata.policyVerificationOutcomes:[],me=Q.find(B=>B.status==="failed"),mt=Q.filter(B=>B.status==="passed");me?(k="negative",w="policy_verification_failed",q=typeof me.receiptId=="string"?me.receiptId:void 0):mt.length>0&&(k="positive",w="policy_verification_passed",q=typeof mt.at(-1)?.receiptId=="string"?String(mt.at(-1).receiptId):void 0),L=h.getActiveContextReceipt(t,i,g)?.contextHash,lt=Q.map(B=>B.command).filter(B=>typeof B=="string");}L&&(X=h.getSemanticExecutionContextByHash(L)?.dispositions.filter(O=>O.requirement==="required").map(O=>O.channel)??[]);}finally{h.close();}let xn=No({projectRoot:t,sessionId:i,executionId:g,outcome:k,outcomeReason:w,verificationReceipt:q,requiredChannels:X,finishedAt:p}),Ti=await b.attributeRetrievalBenefits({sessionId:i,executionId:g,outcome:k,outcomeReason:w,workflowRunId:ue,contextReceipt:L,toolEvidence:lt,verificationReceipt:q,consumedSourceIds:xn.consumedSources.filter(V=>V.sourceType==="memory").map(V=>V.sourceId)});A={status:v?"evaluated":"unknown",...Ti,retrievalLedger:xn};}catch(v){A={...A,status:"degraded",reason:H(v)};}let x;try{x=await b.reconcileDecidedTurnEventWindows(i,y,p);}catch(v){let h=H(v),k={...R,...d,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:h,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"event_reconciliation",reason:h,metadata:k}),new G("event_reconciliation",h)}let D;try{D=await fe({projectRoot:t,sessionId:i,trigger:"session_end",memory:b,details:{eventReconciliation:x},strictPersistence:!0});}catch(v){let h=H(v),k={...R,...d,memoryEventReconciliation:{status:"completed",...x,checkpointPending:null},memoryCheckpointDegradation:h};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"checkpoint",reason:h,metadata:k}),new G("checkpoint",h)}let P={memoryLineageReconciliation:_,memoryBenefitAttribution:A,memoryEventReconciliation:{status:"completed",...x,checkpointPending:D.pendingEvents},memoryDistillCheckpoint:D};try{let v=openGlobalDevFlowDatabase();try{let h=`session-finalize:${i}:events`,k=Math.max(Number(D.pendingEvents??0),Number(x.remainingUndecided??0)),w=v.getSessionObligation(t,i,h);k>0?v.upsertSessionObligation({obligationId:h,projectRoot:t,sessionId:i,executionId:g,kind:"session_finalize",state:"open",payload:{pendingEvents:k,reconciliation:x,checkpointId:D.id},reason:"active_unprocessed_session_events",createdAt:w?.createdAt??p,updatedAt:p}):w?.state==="open"&&v.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:h,state:"satisfied",reason:"session_events_reconciled",resolvedAt:p});}finally{v.close();}}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"obligation_persistence",reason:H(v)}});}try{await b.closeSession(i),f&&(f.close(),f=void 0);}catch(v){let h=H(v),k={...R,...d,...P,memorySessionCloseDegradation:h};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"memory_close",reason:h,metadata:k}),new G("memory_close",h)}let M={...R,...d,...P},E=[];try{let v=openGlobalDevFlowDatabase();try{let h=new Map(v.listLatestTaskIntentArtifacts(t,i).map(k=>[k.turnId,k]));for(let k of y){let w=h.get(k.turnId);if(!w)continue;let L=[v.getWorkByIdempotencyKey(`memory-turn:capture_prompt:${k.turnId}`),v.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${k.turnId}`)].filter(Boolean).some(X=>X.state==="pending"||X.state==="leased"||X.state==="failed"),q=Uo({artifact:w,memoryStatus:k.status,memoryReceiptId:k.receiptId,retryOwned:L,reason:k.status==="pending"?"session_end_memory_pending":"session_end_reconciled"});E.push({turnId:k.turnId,state:q.toState,receiptId:q.receiptId});}}finally{v.close();}}catch(v){E.push({state:"terminal_integrity_failure",reason:H(v)});}M.terminalOutcomes=E,m=!0;let S;try{S=openGlobalDevFlowDatabase();let v=g;if(v)try{S.reconcileSkillExecution(v,"completed",p,M);let w=S.getSkillExecution(v);await K("/api/telemetry/skill-execution/complete",{executionId:v,finishedAt:p,status:"completed",summary:{totalToolCalls:w?.totalToolCalls??0,mcpToolCalls:w?.mcpToolCalls??0,directToolCalls:w?.directToolCalls??0,subagentCount:w?.subagentCount??0,totalDuration:w?.totalDuration??0,mcpComplianceRate:w?.mcpComplianceRate??0,missedTools:w?.missedMcpTools??[],actualFailureCount:w?.failedToolCalls??0,fallbackCount:w?.fallbackCount??0,fallbackReasons:w?.fallbackReasons??[]},metadata:M},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let h=S.reconcileRunningSkillExecutionsForSession(i,p,{closureReason:"session_finalize",...M});for(let w of h)await K("/api/telemetry/skill-execution/complete",{executionId:w.executionId,finishedAt:w.finishedAt,status:w.status,summary:{totalToolCalls:w.totalToolCalls??0,mcpToolCalls:w.mcpToolCalls??0,directToolCalls:w.directToolCalls??0,subagentCount:w.subagentCount??0,totalDuration:w.totalDuration??0,mcpComplianceRate:w.mcpComplianceRate??0,missedTools:w.missedMcpTools??[],actualFailureCount:w.failedToolCalls??0,fallbackCount:w.fallbackCount??0,fallbackReasons:w.fallbackReasons??[]},metadata:M},{fallbackReason:"skill_execution_already_reconciled_locally"});let k=S.getLatestSkillExecutionForSession(i);if(k&&!h.some(w=>w.executionId===k.executionId)&&S.mergeSkillExecutionMetadata(k.executionId,M),n){S.deleteHookReceipt(t);let w=$(t),ue=createHash("sha256").update(t).digest("hex").slice(0,12);for(let L of [`session-id-${ue}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(w,L),{force:!0});}S.deleteContextReceipt(t,i);}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"lifecycle_telemetry",reason:H(v),fallback:"fail_open"}});}finally{S?.close();}try{await u.endSession(i),await u.flushAndAggregate();}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"telemetry_flush",reason:H(v),fallback:"local_state_authoritative"}});}}finally{if(f)try{f.close();}catch{}l&&u.close(),m&&s.removeSession(i),I({event:m?"hook.session_end.completed":"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:o?.executionId??a?.executionId},level:m?"info":"warn",timestamp:Date.now(),data:{stage:"finalize",criticalStagesCompleted:m,transcriptStatus:c.status}});}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let e=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n;}),process.stdin.on("end",async()=>{let n=Ve(t.trim()||process.argv[2]||"");n&&e(JSON.stringify(n)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var xc=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ec=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Tc=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Ac=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function Ie(e){let t=e.trim().replace(xc,"").trim();return !t||Ec.test(t)?null:(Ac.exec(t)??Tc.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Dc(e){return join(getProjectStateDir(e),"memory-intents.jsonl")}function Cc(e){try{return readFileSync$1(e,"utf8").split(`
17
+ `).slice(0,4e3)}var ac={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 Uo(e){return cc(e)}function cc(e){let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let n=mc(t,e.artifact);if(pc(n.toState))return n;let o=t.getContextReceiptForRequest(e.artifact.projectRoot,e.artifact.sessionId,e.artifact.requestId),r=t.getMemoryTurn(e.artifact.turnId),i=e.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return n;let s=o?dc(e.artifact,o):"context_ready";n.toState==="intent_bound"&&(n=F(t,n,e,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?lc(e.artifact,o):"action_not_required";if((n.toState==="context_ready"||n.toState==="context_degraded")&&(a==="action_not_required"?n=F(t,n,e,"action_not_required","task_action_not_required"):n=F(t,n,e,"action_required","canonical_action_obligation_present")),n.toState==="action_required"){if(a==="action_required")return n;if(a==="action_failed")return F(t,n,e,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?n=F(t,n,e,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(n=F(t,n,e,"action_satisfied","canonical_action_succeeded"));}if(n.toState==="action_failed")if(a==="action_satisfied")n=F(t,n,e,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")n=F(t,n,e,"action_degraded","canonical_action_retry_degraded");else return n;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(n.toState)&&(n=F(t,n,e,e.memoryStatus==="pending"?"memory_quarantined":"memory_decided",e.memoryStatus==="pending"?e.reason:`canonical_memory_${e.memoryStatus}`)),n.toState==="memory_decided"?F(t,n,e,c?"closed_with_degradation":"closed",e.reason):n.toState==="memory_quarantined"?F(t,n,e,e.retryOwned?"closed_with_retry_work":"closed_with_degradation",e.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):n}finally{t.close();}}function dc(e,t){return e.intent==="memory"||e.intent==="knowledge"||(t.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function lc(e,t){let n=t.canonicalAction,r=(n?(t.actionAttempts??[]).filter(i=>i.tool===n.tool):[]).at(-1);return t.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":t.actionDegradation||n?.status==="degraded"||n?.status==="unsupported"?"action_degraded":n?.required||uc(e)?"action_required":"action_not_required"}function uc(e){return ["create","modify","debug","test","format"].includes(e.action)||["feature","refactor","performance"].includes(e.intent)}function mc(e,t){let n=e.getLatestTerminalTransition(t.projectRoot,t.sessionId,t.turnId);if(!n)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${t.turnId}`);return n}function F(e,t,n,o,r){if(!ac[t.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${t.toState}->${o}`);let i=t.sequence+1,s=`terminal:${createHash("sha256").update(`${n.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=e.appendTerminalTransition({projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,executionId:n.artifact.executionId,sequence:i,fromState:t.toState,toState:o,receiptId:s,sourceReceiptId:n.memoryReceiptId??t.receiptId,reason:r,payload:{memoryStatus:n.memoryStatus,retryOwned:n.retryOwned??false,sourceIntentHash:n.artifact.artifactHash},createdAt:Date.now()});return I({event:"terminal.state.transitioned",identity:{projectRoot:n.artifact.projectRoot,projectId:n.artifact.projectId,hostId:n.artifact.hostId,sessionId:n.artifact.sessionId,turnId:n.artifact.turnId,requestId:n.artifact.requestId,...n.artifact.executionId?{executionId:n.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:t.toState,nextState:o,receiptId:s,reason:r}}),a}function pc(e){return e==="closed"||e==="closed_with_degradation"||e==="closed_with_retry_work"}var fc=new Set(["delivered","cancelled","rejected"]),gc=new Set(["cancelled","rejected"]),yc=new Set(["Write","Edit","NotebookEdit","Bash"]);function hc(e,t){if(e!=="Bash"||typeof t?.command!="string")return false;let o="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${o}(?: \\|\\| ${o})*$`,"u").test(t.command)}function Ko(e,t){let n=join(e,".devflow","delivery-line","state.db");if(!existsSync(n)||!t.trim())return 0;let o;try{o=new DatabaseSync(n,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(t,t),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let d=JSON.parse(a.payload);c=d.evidence?.some(u=>u.metadata?.trust==="external-untrusted")?"untrusted":d.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let d=`session.closed:${a.id}:${t}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(d,a.id,d,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:t,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function Jo(e,t,n,o,r){if(n.includes("delivery_rebind_session")||!yc.has(n)||!t.trim()||hc(n,r))return null;let i=join(e,".devflow","delivery-line","state.db");if(!existsSync(i))return null;let s;try{s=new DatabaseSync(i,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let p of f){let g=[];try{g=JSON.parse(p.aliases);}catch{}(p.source_path===e||g.includes(e))&&c.add(p.case_id);}}let u=[];for(let f of a){let p=JSON.parse(f.payload),g=c.has(f.id);(p.sessionId===t||t===f.id||g)&&u.push({id:f.id,payload:p,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof p.updatedAt=="number"?p.updatedAt:0});let y=typeof p.stage=="string"?p.stage:"unknown";if(!fc.has(y)){if(o&&y==="executing"){let R=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),b=typeof p.sessionId=="string"?p.sessionId:void 0,_=typeof p.executionId=="string"?p.executionId:void 0,A=o===R?.id||o===R?.lease_owner||o===_,x=t===f.id||t===b;if(R?.id&&A&&x)return null}if(p.sessionId===t||t===f.id||g)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:y,message:`Delivery case ${f.id} is ${y}; use the Delivery task lease before modifying files.`}}}let l=u.sort((f,p)=>p.updatedAt-f.updatedAt)[0],m=typeof l?.payload.stage=="string"?l.payload.stage:void 0;return l&&m&&gc.has(m)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:l.id,stage:m,message:`Delivery case ${l.id} is ${m}; start a new Delivery case or session before modifying files.`}:null}catch{return {code:"DELIVERY_AUTHORITY_UNAVAILABLE",caseId:"unknown",stage:"unknown",message:"Delivery state cannot be read; file writes are blocked until runtime health is restored."}}finally{s?.close();}}function Ot(e){let t={committed:0,skipped:0,pending:0},n=[];for(let o of e)t[o.status]+=1,o.receiptId&&n.push(o.receiptId);return {memoryReceiptIds:[...new Set(n)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function H(e){return (e instanceof Error?e.message:String(e)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var G=class extends Error{constructor(t,n){super(`session_finalize_${t}:${n}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function ve(e){let t;try{t=openGlobalDevFlowDatabase();let n=(e.executionId?t.getSkillExecution(e.executionId):null)??t.getLatestSkillExecutionForSession(e.sessionId),o={stage:e.stage,reason:e.reason,degradedAt:Date.now()};n&&t.mergeSkillExecutionMetadata(n.executionId,{...e.metadata,sessionFinalizationDegradations:[o]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId,...o}}),I({event:"hook.session_end.degraded",identity:{projectRoot:e.projectRoot,sessionId:e.sessionId,executionId:n?.executionId},level:"warn",timestamp:o.degradedAt,data:{stage:e.stage,reason:e.reason}});}catch{}finally{t?.close();}}function Ve(e,t=Ce(),n=true,o,r=true){let i;try{i=JSON.parse(e);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:e,sessionId:s,cleanupSharedState:n,executionId:o};try{Ko(t,s);}catch{}let d;try{d=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let u=d.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),l=d.getWorkByIdempotencyKey(a),m={status:u.state==="closed"||u.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:l?.state??"pending",closureState:u.state,pendingWorkCount:u.pendingWorkCount,...l?.id?{workItemId:l.id}:{}};return I({event:"hook.session_end.completed",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(u){if(!r)throw u;return bo(t,{receiptId:a,...c}),I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:H(u),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{d?.close();}}async function Yo(e,t=Ce(),n=true,o){let r;try{r=JSON.parse(e);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new N(t),a=s.get(i),c=Wo({projectRoot:t,sessionId:i,transcriptPath:r.transcript_path}),d={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(p=>p.contractId)??[],transcriptReconciliation:c},u=o?.telemetry??new ee,l=!o?.telemetry,m=false,f;try{try{await u.flushAndAggregate();}catch{}let p=Date.now(),g=o?.executionId??a?.executionId,y;try{let v=openGlobalDevFlowDatabase();try{y=v.listSessionMemoryTurnsForReconciliation(t,i);for(let h of y){let k=`memory:${h.turnId}`,w=v.getSessionObligation(t,i,k);w?w.state==="open"&&h.status!=="pending"&&v.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:k,state:"satisfied",receiptId:h.receiptId,reason:h.reason,resolvedAt:h.decidedAt}):v.upsertSessionObligation({obligationId:k,projectRoot:t,sessionId:i,turnId:h.turnId,kind:"memory_decision",state:h.status==="pending"?"open":"satisfied",payload:{eventId:h.eventId,promptHash:h.promptHash},receiptId:h.receiptId,reason:h.reason,createdAt:h.createdAt,updatedAt:h.decidedAt??h.createdAt,resolvedAt:h.decidedAt});}}finally{v.close();}}catch(v){let h=H(v),k={...d,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:h,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"turn_load",reason:h,metadata:k}),new G("turn_load",h)}let R=Ot(y),b=o?.memory??(f=new MemoryGate(t)),_={status:"completed"};try{_=typeof b.reconcileTurnObservationLineage=="function"?{status:"completed",...await b.reconcileTurnObservationLineage(y)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(v){let h=H(v);throw _={status:"degraded",reason:h},ve({projectRoot:t,sessionId:i,executionId:g,stage:"memory_lineage",reason:h,metadata:{...R,...d,memoryLineageReconciliation:_}}),new G("memory_lineage",h)}let A={status:"unknown",selected:0,consumed:0,unknown:0,positive:0,negative:0};try{let v=ze(r.transcript_path),h=openGlobalDevFlowDatabase(),k="unknown",w="no_terminal_host_action_evidence",ue,L,q,X=[],lt=[];try{let V=h.listHostActionsForSession(t,i,g),En=V.filter(O=>O.state==="verified"),ut=V.filter(O=>["failed","cancelled","degraded"].includes(O.state));ut.length>0?(k="negative",w=`terminal_host_action_${ut[0].state}`):En.length>0&&(k="positive",w="host_action_verified");let Te=ut[0]??En.at(-1);if(ue=Te?.runId,L=Te?.contextReceipt,q=Te?.evidenceHash,lt=V.flatMap(O=>{let Q=O.report.toolUseIds;return Array.isArray(Q)?Q.filter(me=>typeof me=="string"):[]}),!Te&&g){let O=h.getSkillExecution(g),Q=O?.metadata&&typeof O.metadata=="object"&&Array.isArray(O.metadata.policyVerificationOutcomes)?O.metadata.policyVerificationOutcomes:[],me=Q.find(B=>B.status==="failed"),mt=Q.filter(B=>B.status==="passed");me?(k="negative",w="policy_verification_failed",q=typeof me.receiptId=="string"?me.receiptId:void 0):mt.length>0&&(k="positive",w="policy_verification_passed",q=typeof mt.at(-1)?.receiptId=="string"?String(mt.at(-1).receiptId):void 0),L=h.getActiveContextReceipt(t,i,g)?.contextHash,lt=Q.map(B=>B.command).filter(B=>typeof B=="string");}L&&(X=h.getSemanticExecutionContextByHash(L)?.dispositions.filter(O=>O.requirement==="required").map(O=>O.channel)??[]);}finally{h.close();}let xn=No({projectRoot:t,sessionId:i,executionId:g,outcome:k,outcomeReason:w,verificationReceipt:q,requiredChannels:X,finishedAt:p}),Ti=await b.attributeRetrievalBenefits({sessionId:i,executionId:g,outcome:k,outcomeReason:w,workflowRunId:ue,contextReceipt:L,toolEvidence:lt,verificationReceipt:q,consumedSourceIds:xn.consumedSources.filter(V=>V.sourceType==="memory").map(V=>V.sourceId)});A={status:v?"evaluated":"unknown",...Ti,retrievalLedger:xn};}catch(v){A={...A,status:"degraded",reason:H(v)};}let x;try{x=await b.reconcileDecidedTurnEventWindows(i,y,p);}catch(v){let h=H(v),k={...R,...d,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:h,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"event_reconciliation",reason:h,metadata:k}),new G("event_reconciliation",h)}let D;try{D=await fe({projectRoot:t,sessionId:i,trigger:"session_end",memory:b,details:{eventReconciliation:x},strictPersistence:!0});}catch(v){let h=H(v),k={...R,...d,memoryEventReconciliation:{status:"completed",...x,checkpointPending:null},memoryCheckpointDegradation:h};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"checkpoint",reason:h,metadata:k}),new G("checkpoint",h)}let P={memoryLineageReconciliation:_,memoryBenefitAttribution:A,memoryEventReconciliation:{status:"completed",...x,checkpointPending:D.pendingEvents},memoryDistillCheckpoint:D};try{let v=openGlobalDevFlowDatabase();try{let h=`session-finalize:${i}:events`,k=Math.max(Number(D.pendingEvents??0),Number(x.remainingUndecided??0)),w=v.getSessionObligation(t,i,h);k>0?v.upsertSessionObligation({obligationId:h,projectRoot:t,sessionId:i,executionId:g,kind:"session_finalize",state:"open",payload:{pendingEvents:k,reconciliation:x,checkpointId:D.id},reason:"active_unprocessed_session_events",createdAt:w?.createdAt??p,updatedAt:p}):w?.state==="open"&&v.resolveSessionObligation({projectRoot:t,sessionId:i,obligationId:h,state:"satisfied",reason:"session_events_reconciled",resolvedAt:p});}finally{v.close();}}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"obligation_persistence",reason:H(v)}});}try{await b.closeSession(i),f&&(f.close(),f=void 0);}catch(v){let h=H(v),k={...R,...d,...P,memorySessionCloseDegradation:h};throw ve({projectRoot:t,sessionId:i,executionId:g,stage:"memory_close",reason:h,metadata:k}),new G("memory_close",h)}let M={...R,...d,...P},E=[];try{let v=openGlobalDevFlowDatabase();try{let h=new Map(v.listLatestTaskIntentArtifacts(t,i).map(k=>[k.turnId,k]));for(let k of y){let w=h.get(k.turnId);if(!w)continue;let L=[v.getWorkByIdempotencyKey(`memory-turn:capture_prompt:${k.turnId}`),v.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${k.turnId}`)].filter(Boolean).some(X=>X.state==="pending"||X.state==="leased"||X.state==="failed"),q=Uo({artifact:w,memoryStatus:k.status,memoryReceiptId:k.receiptId,retryOwned:L,reason:k.status==="pending"?"session_end_memory_pending":"session_end_reconciled"});E.push({turnId:k.turnId,state:q.toState,receiptId:q.receiptId});}}finally{v.close();}}catch(v){E.push({state:"terminal_integrity_failure",reason:H(v)});}M.terminalOutcomes=E,m=!0;let S;try{S=openGlobalDevFlowDatabase();let v=g;if(v)try{S.reconcileSkillExecution(v,"completed",p,M);let w=S.getSkillExecution(v);await K("/api/telemetry/skill-execution/complete",{executionId:v,finishedAt:p,status:"completed",summary:{totalToolCalls:w?.totalToolCalls??0,mcpToolCalls:w?.mcpToolCalls??0,directToolCalls:w?.directToolCalls??0,subagentCount:w?.subagentCount??0,totalDuration:w?.totalDuration??0,mcpComplianceRate:w?.mcpComplianceRate??0,missedTools:w?.missedMcpTools??[],actualFailureCount:w?.failedToolCalls??0,fallbackCount:w?.fallbackCount??0,fallbackReasons:w?.fallbackReasons??[]},metadata:M},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let h=S.reconcileRunningSkillExecutionsForSession(i,p,{closureReason:"session_finalize",...M});for(let w of h)await K("/api/telemetry/skill-execution/complete",{executionId:w.executionId,finishedAt:w.finishedAt,status:w.status,summary:{totalToolCalls:w.totalToolCalls??0,mcpToolCalls:w.mcpToolCalls??0,directToolCalls:w.directToolCalls??0,subagentCount:w.subagentCount??0,totalDuration:w.totalDuration??0,mcpComplianceRate:w.mcpComplianceRate??0,missedTools:w.missedMcpTools??[],actualFailureCount:w.failedToolCalls??0,fallbackCount:w.fallbackCount??0,fallbackReasons:w.fallbackReasons??[]},metadata:M},{fallbackReason:"skill_execution_already_reconciled_locally"});let k=S.getLatestSkillExecutionForSession(i);if(k&&!h.some(w=>w.executionId===k.executionId)&&S.mergeSkillExecutionMetadata(k.executionId,M),n){S.deleteHookReceipt(t);let w=$(t),ue=createHash("sha256").update(t).digest("hex").slice(0,12);for(let L of [`session-id-${ue}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(w,L),{force:!0});}S.deleteContextReceipt(t,i);}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"lifecycle_telemetry",reason:H(v),fallback:"fail_open"}});}finally{S?.close();}try{await u.endSession(i),await u.flushAndAggregate();}catch(v){I({event:"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:g},level:"warn",timestamp:Date.now(),data:{stage:"telemetry_flush",reason:H(v),fallback:"local_state_authoritative"}});}}finally{if(f)try{f.close();}catch{}l&&u.close(),m&&s.removeSession(i),I({event:m?"hook.session_end.completed":"hook.session_end.degraded",identity:{projectRoot:t,sessionId:i,executionId:o?.executionId??a?.executionId},level:m?"info":"warn",timestamp:Date.now(),data:{stage:"finalize",criticalStagesCompleted:m,transcriptStatus:c.status}});}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let e=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{t+=n;}),process.stdin.on("end",async()=>{let n=Ve(t.trim()||process.argv[2]||"");n&&e(JSON.stringify(n)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var xc=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ec=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Tc=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Ac=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function Ie(e){let t=e.trim().replace(xc,"").trim();return !t||Ec.test(t)?null:(Ac.exec(t)??Tc.exec(t))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Dc(e){return join(getProjectStateDir(e),"memory-intents.jsonl")}function Cc(e){try{return readFileSync$1(e,"utf8").split(`
18
18
  `).filter(Boolean).flatMap(t=>{try{let n=JSON.parse(t);return typeof n.content=="string"&&typeof n.createdAt=="number"?[n]:[]}catch{return []}})}catch{return []}}function tr(e){let t=Dc(e),n=`${t}.claim-`,o=`${basename(t)}.claim-`,r=(()=>{try{return readdirSync$1(dirname$1(t)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(t),r):`${n}${Date.now()}-${process.pid}`;if(!r)try{renameSync(t,i);}catch{return null}let s=Cc(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function Pt(e){if(e.intents.shift(),e.intents.length===0){try{unlinkSync$1(e.path);}catch{}return}let t=`${e.path}.tmp-${process.pid}`;writeFileSync$1(t,e.intents.map(n=>JSON.stringify(n)).join(`
19
19
  `)+`
20
20
  `,{mode:384}),renameSync(t,e.path);}function Be(e){let t=e.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let n=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(n)?`devflow:${n.toLowerCase()}`:null}function nr(e){let t=e.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let n=Be(t[1]);return n?{rawName:t[1],skillName:n}:null}function we(e,t){return t?`evt_tool_${createHash$1("sha256").update(`${e}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var ke=1,qt="memory-snapshot-v1.json",fr=512*1024,gr=256*1024,yr=2e3,Nc=500,Lc=10,qc=240,Wc=300*1e3,Uc=720*60*60*1e3,hr=2147483647,zc=100,sr=250,Vc=3e4,Bc=10,Ke=new Map;function vr(e){return e.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:e.ownerUid===e.currentUid,modeSafe:(e.mode&18)===0}}function Y(e){return resolve(e)}function se(e){return createHash("sha256").update(Y(e)).digest("hex").slice(0,16)}function Wt(e,t={}){let n=se(e),o=t.stateRoot?join(t.stateRoot,n):getProjectStateDir(Y(e));return join(o,qt)}function Ge(e,t){let o=(e instanceof Error?e.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${t}:${o}`:t}function Ut(e,t){return Array.isArray(e)&&e.length<=t&&e.every(n=>typeof n=="string"&&n.length>0&&n.length<=512)}function Kc(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return typeof t.id=="string"&&t.id.length>0&&t.id.length<=512&&typeof t.kind=="string"&&t.kind.length>0&&t.kind.length<=128&&(t.family===void 0||typeof t.family=="string"&&t.family.length>0&&t.family.length<=256)&&(t.entity===void 0||typeof t.entity=="string"&&t.entity.length>0&&t.entity.length<=256)&&Ut(t.memoryIds,100)&&(t.status==="withheld"||t.status==="resolved")&&(t.summary===void 0||typeof t.summary=="string"&&t.summary.length<=2e3)}function Jc(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return typeof t.reason=="string"&&t.reason.length>0&&t.reason.length<=512&&(t.stale===void 0||typeof t.stale=="boolean")}function zt(e,t,n){if(!e||typeof e!="object"||Array.isArray(e))return null;let o=e,r=Y(t),i=se(r),s=o.generation===void 0?0:o.generation;return o.version!==ke||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>gr||!Ut(o.memoryIds,yr)||!Array.isArray(o.conflicts)||o.conflicts.length>Nc||!o.conflicts.every(Kc)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>n+Wc||!Number.isInteger(s)||s<0||s>hr||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Jc(o.degradation)?null:{...o,generation:s}}function Vt(e,t,n,o,r=0){let i=Y(e);return {version:ke,projectRoot:i,projectHash:se(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:t,degradation:{reason:n}}}function re(e,t={}){let n=t.now??Date.now(),o=Wt(e,t),r;try{r=openSync$1(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync$1(r);if(!i.isFile()||i.size<=0||i.size>fr)throw new Error("cache_size_invalid");let s=vr({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync$1(r,"utf8")),c=zt(a,e,n);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&n-c.generatedAt>Uc?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Vt(e,a?"pending":"degraded",a?"cache_missing":Ge(i,"cache_invalid"),n),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync$1(r);}catch{}}}function ar(e){if(!Number.isInteger(e)||e<0||e>=hr)throw new Error("memory_snapshot_generation_exhausted");return e+1}function Gc(e){let t=dirname$1(e);mkdirSync$1(t,{recursive:true,mode:448}),chmodSync(t,448);}function Yc(e){Gc(e);let t=`${e}.lock`,n={pid:process.pid,createdAt:Date.now(),token:randomUUID$1()},o=JSON.stringify(n),r;try{return r=openSync$1(t,"wx",384),writeFileSync$1(r,o),fsyncSync(r),{fd:r,path:t,contents:o}}catch(i){if(r!==void 0){try{closeSync$1(r);}catch{}try{unlinkSync$1(t);}catch{}}if(i.code==="EEXIST")return null;throw i}}function Xc(e){if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return Number.isInteger(t.pid)&&Number(t.pid)>0&&typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.token=="string"&&t.token.length>0}function Qc(e){try{return process.kill(e,0),!1}catch(t){return t.code==="ESRCH"}}function Zc(e){return !e.canonicalCachePath||!e.directoryIsSafe||!e.lockIsRegularFile||!e.metadataValid||!e.contentsUnchanged||!e.ownerDead&&!e.stale?false:e.currentUid!==void 0?e.directoryUid===e.currentUid&&e.lockUid===e.currentUid:true}function ed(e){return isAbsolute(e)&&resolve(e)===e&&basename(e)===qt&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(e)))}function td(e,t){let n=`${e}.lock`;try{let o=lstatSync$1(dirname$1(e)),r=lstatSync$1(n),i=readFileSync$1(n,"utf8"),s=null;try{let f=JSON.parse(i);Xc(f)&&(s=f);}catch{}let a=s?.createdAt??r.mtimeMs,c=Date.now()-a>t,d=s?Qc(s.pid):!1,u=readFileSync$1(n,"utf8")===i,l=typeof process.getuid=="function"?process.getuid():void 0,m=vr({...l!==void 0?{currentUid:l}:{},ownerUid:o.uid,mode:o.mode});return Zc({canonicalCachePath:ed(e),directoryIsSafe:o.isDirectory()&&!o.isSymbolicLink()&&m.modeSafe,lockIsRegularFile:r.isFile()&&!r.isSymbolicLink(),metadataValid:s!==null,ownerDead:d,stale:c,contentsUnchanged:u,...l!==void 0?{currentUid:l}:{},directoryUid:o.uid,lockUid:r.uid})?(unlinkSync$1(n),!0):!1}catch{return false}}function nd(e){try{closeSync$1(e.fd);}catch{}try{readFileSync$1(e.path,"utf8")===e.contents&&unlinkSync$1(e.path);}catch{}}function od(e){return new Promise(t=>setTimeout(t,e))}function jt(e,t,n,o){let r=Number.isFinite(e)?Math.floor(e):t;return Math.min(o,Math.max(n,r))}async function rd(e,t){let n=jt(t.lockTimeoutMs,zc,0,sr),o=jt(t.lockRetryMs,Bc,1,sr),r=jt(t.lockStaleMs,Vc,0,Number.MAX_SAFE_INTEGER),i=Date.now()+n;for(;;){let s=Yc(e);if(s)return s;if(td(e,r))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await od(Math.min(o,a));}}async function cr(e,t,n){let o=await rd(e,t);try{return await n()}finally{nd(o);}}function dr(e,t,n,o){let r=o.now??Date.now(),i=Y(e),s={version:ke,projectRoot:i,projectHash:se(i),markdown:t.markdown,memoryIds:t.memoryIds??[],conflicts:t.conflicts??[],generatedAt:r,generation:n,status:t.status??"ready",...t.degradation?{degradation:t.degradation}:{}};if(!zt(s,e,r))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>fr)throw new Error("memory_snapshot_cache_too_large");let c=Wt(e,o),d=dirname$1(c);mkdirSync$1(d,{recursive:true,mode:448}),chmodSync(d,448);let u=join(d,`.${qt}.${process.pid}.${randomUUID$1()}.tmp`),l;try{l=openSync$1(u,"wx",384),writeFileSync$1(l,a),fsyncSync(l),closeSync$1(l),l=void 0,chmodSync(u,384),renameSync(u,c),chmodSync(c,384);let m;try{m=openSync$1(d,"r");try{fsyncSync(m);}catch{}}finally{m!==void 0&&closeSync$1(m);}return s}finally{if(l!==void 0)try{closeSync$1(l);}catch{}rmSync$1(u,{force:true});}}function id(e,t){let o=(Ke.get(e)??Promise.resolve()).catch(()=>{}).then(t),r=o.then(()=>{},()=>{});return Ke.set(e,r),o.finally(()=>{Ke.get(e)===r&&Ke.delete(e);})}function $t(e,t,n,o,r){return e.valid?e.snapshot.generation>r?{...e,persisted:false}:{...e,snapshot:{...e.snapshot,status:"degraded",degradation:{reason:n,stale:e.stale||void 0}},persisted:false}:{snapshot:Vt(t,"degraded",n,o,r),source:"none",valid:false,stale:false,persisted:false}}async function Bt(e){let t=Wt(e.projectRoot,e.cacheOptions);return id(t,async()=>{let n=re(e.projectRoot,e.cacheOptions),o=n.valid?n.snapshot.generation:0,r;try{r=await e.load();}catch(i){let s=Ge(i,`refresh_failed:${e.reason}`);try{return await cr(t,e.cacheOptions??{},()=>{let a=re(e.projectRoot,e.cacheOptions);if(a.valid)return $t(a,e.projectRoot,s,e.cacheOptions?.now??Date.now(),o);let c=ar(o),d=Vt(e.projectRoot,"degraded",s,e.cacheOptions?.now??Date.now(),c);return {snapshot:dr(e.projectRoot,d,c,e.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=re(e.projectRoot,e.cacheOptions);return $t(c,e.projectRoot,Ge(a,s),e.cacheOptions?.now??Date.now(),o)}}try{return await cr(t,e.cacheOptions??{},()=>{let i=re(e.projectRoot,e.cacheOptions);if(i.valid&&i.snapshot.generation>o)return {...i,persisted:!1};let s=ar(Math.max(o,i.valid?i.snapshot.generation:0));return {snapshot:dr(e.projectRoot,r,s,e.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=re(e.projectRoot,e.cacheOptions);return $t(s,e.projectRoot,Ge(i,`refresh_commit_failed:${e.reason}`),e.cacheOptions?.now??Date.now(),o)}})}async function Qe(e){return Bt({projectRoot:e.projectRoot,reason:e.reason,cacheOptions:e.cacheOptions,load:async()=>{if(e.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let t=typeof e.injectConfig=="object"?e.injectConfig:{},n=Number.isFinite(t.topN)?Math.max(0,Math.floor(t.topN)):4,o=Number.isFinite(t.budgetTokens)?Math.max(1,Math.floor(t.budgetTokens)):400,r=await e.memory.getAll({purpose:"session_bootstrap",budgetTokens:o,limit:n}),s=Number.isInteger(r.truncatedCount)&&r.truncatedCount>=0?r.truncatedCount:null,a=r.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",d=(r.conflicts??[]).map(l=>({id:l.id,kind:l.kind,family:l.family,entity:l.entity,memoryIds:l.memoryIds,status:l.status,...l.summary?{summary:l.summary}:{}})),u=a?`## Project memory
@@ -1,4 +1,4 @@
1
- import {existsSync,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {createHash as createHash$1}from'node:crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function P(i,t,e){try{let n=openGlobalDevFlowDatabase();try{n.insertEvent({kind:i,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{n.close();}}catch{}}var ct=getLocalApiKey(),V=join(getDevFlowStateRoot(),"errors");async function ce(i,t,e={}){let n=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??lt();if(!n)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),c=e.circuitBreaker??true,a=acquireRuntimeHttpCircuit(n,i);if(c&&!a.allowed)return {delivered:false,suppressed:true,fallbackReason:a.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await dt(n,i,t,o),c&&registerRuntimeHttpSuccess(n,i).transitioned&&P("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await ut(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!c)return se(i,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(n,i,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(se(i,l),P("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function lt(){let i=readRuntimeState();return i?.status==="ready"&&i.dashboardAvailable?i.url:void 0}function dt(i,t,e,n){return new Promise((o,r)=>{let s=JSON.stringify(e),c=new URL(t,i),a=false,l=u=>{a||(a=true,u?r(u):o());},d=request({hostname:c.hostname,port:c.port,path:c.pathname+c.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":ct,"Content-Length":Buffer.byteLength(s)},timeout:n},u=>{u.on("error",l),u.on("end",()=>{let p=u.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),d.write(s),d.end();})}function se(i,t){try{existsSync$1(V)||mkdirSync$1(V,{recursive:!0});let e=join(V,"http-errors.log"),n=`${new Date().toISOString()} | ${i} | ${t.message}
2
- `;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(n)}),appendFileSync(e,n);}catch{}}function ut(i){return new Promise(t=>setTimeout(t,i))}var pe=1e4,yt=3e4,M=500,N=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,o,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let c={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}async sendExecutionComplete(t,e="completed",n=Date.now(),o){let r={executionId:t,status:e,finishedAt:n,metadata:o},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,n){let o={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",o);return r&&this.postHttp("/api/telemetry/sessions",o),r}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",n);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let e=this.getDatabase(),n=e.listTelemetryFailures({unresolvedOnly:!0,limit:M}).reverse();for(let o of n)try{this.applyOperation(o.operation,o.payload),e.resolveTelemetryFailure(o.id);}catch{}e.trimTelemetryFailures(M);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let n=join$1(this.cacheDir,e);try{return {cacheFile:n,envelope:vt(JSON.parse(readFileSync(n,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,n)=>e.envelope.timestamp-n.envelope.timestamp||ge(e.envelope.operation)-ge(n.envelope.operation));for(let{cacheFile:e,envelope:n}of t)try{let o=this.getDatabase();o.insertTelemetryFailure({id:n.id,operation:n.operation,payload:n.payload,error:n.failure,createdAt:n.timestamp}),this.applyOperation(n.operation,n.payload),o.resolveTelemetryFailure(n.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:fe(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(fe(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let o=Date.now(),r={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:o}),s.trimTelemetryFailures(M),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-M)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},yt).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){ce(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=pe?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,pe)}...`}}};function ge(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function fe(i){return `hook-run:${i}`}function vt(i){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let t=i;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function C(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(i){return getProjectStateDir(C(i))}var D=emitSemanticControlLog;var It=2,xt=1;function kt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function me(i=kt()){let t=[join$1(i,"dist","command-registry.json"),join$1(i,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let n=JSON.parse(readFileSync(e,"utf8"));if(n.version!==It&&n.version!==xt||!St(n.commands)){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return n.commands}catch(n){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:n.message,fallback:"next_registry_candidate"}});}return null}function St(i){return !i||typeof i!="object"||Array.isArray(i)?false:Object.values(i).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return U(e.mcpTools)&&U(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||U(e.runtimePackages))&&(e.hostTools===void 0||Ot(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Ot(i){return !!i&&typeof i=="object"&&!Array.isArray(i)&&Object.entries(i).every(([t,e])=>t.length>0&&U(e))}function U(i){return Array.isArray(i)&&i.every(t=>typeof t=="string"&&t.length>0)}function he(i){let t=me();return t?t[i]?.mcpTools??[]:[]}function _e(i){return Buffer.from(i,"utf8").toString("base64url")}function Ft(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function xe(i){return `${i}:legacy-journal`}var x=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(w(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let o=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,n){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(n)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(t,e){let n=this.registerSession(t);return n.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},n.lastActivityAt=Date.now(),this.persist(n),n}completeContextInitialization(t,e){let n=this.get(t);return n?(e&&n.contextInitialization?.toolUseId&&n.contextInitialization.toolUseId!==e||(delete n.contextInitialization,n.lastActivityAt=Date.now(),this.persist(n)),n):null}bindTaskIdentity(t,e){let n=this.registerSession(t);return n.activeTurnId=e.turnId,n.activeRequestId=e.requestId,n.intentArtifactHash=e.intentArtifactHash,n.lastActivityAt=Date.now(),this.persist(n),n}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let r=JSON.parse(readFileSync(o,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=Re(r.evidenceObligations),r.evidenceDegradations=Ee(r.evidenceDegradations),r.evidenceOutcomes=we(r.evidenceOutcomes),this.replayEvidenceJournal(r),this.sessions.set(e,r),r)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),c=(o?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Ft(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:c,contractId:e.id,at:n,contract:e},`add\0${c}`),this.replayEvidenceJournal(r);let a=r.evidenceObligations.find(l=>l.obligationId===c);return a?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(a)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,o,r=Date.now()){let s=this.get(t),c=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!c)return null;let a=/^[a-f0-9]{64}$/.test(o)?o:"";if(!a)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:c.contractId,at:r,fingerprint:a,violations:n.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${a}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let o=n.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}resolveDegradedEvidence(t,e){let n=this.get(t),o=n?.evidenceDegradations.find(s=>s.obligationId===e);if(!n||!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(a=>a.obligationId===e);if(!r||!s)return false;let c=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:c},`degrade\0${e}\0${c}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${_e(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",_e(t))}appendEvidenceEvent(t,e,n){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let r=createHash("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync(s))return;let c=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(c,JSON.stringify(e),{mode:384});try{linkSync(c,s);}catch(a){if(a.code!=="EEXIST")throw a}finally{rmSync(c,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Re(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=we(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let n;try{n=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let o=n.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let c=Lt(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||De(r.kind)-De(s.kind));for(let r of o)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(c=>c.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||n||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let r=o?.attempt??n?.attempt??0;if(e.kind==="resolve"&&n?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(n)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(n,JSON.stringify(t),{mode:384}),renameSync(n,e);}};function Re(i){return Array.isArray(i)?i.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ke(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:xe(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??o;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:n,correctionFingerprint:r}]}).slice(-8):[]}function Ee(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function we(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Lt(i){if(!i||typeof i!="object")return null;let t=i,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:xe(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return ke(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let r=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function De(i){return i==="add"?0:i==="correction"?1:2}function ke(i){if(!i||typeof i!="object")return false;let t=i,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function q(i){if(!i||typeof i!="object"||Array.isArray(i))return {};let t=i,e={};for(let n of ["lastMcpCall","bypassCount"])if(n in t){let o=t[n];if(o==null)continue;e[n]=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;}return e}function jt(i,t){return i.lastMcpCall===t.lastMcpCall&&i.bypassCount===t.bypassCount}function Se(i,t,e){let n=e instanceof Error?e.message:String(e);D({event:"hook.runtime.degraded",identity:{projectRoot:i},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:n,fallback:"fail_open"}});}function Oe(i,t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o={},r=n.updateHookReceipt(i,c=>(o=q(c),q(t(o)))),s=q(r);return {receipt:s,applied:!0,changed:!jt(o,s)}}catch(o){return Se(i,e,o),{receipt:{},applied:false,changed:false}}finally{try{n?.close();}catch{}}}function Ae(i){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),q(t.getHookReceipt(i))}catch(e){return Se(i,"update",e),{}}finally{try{t?.close();}catch{}}}function Pt(i,t){return Oe(i,()=>t,"write").applied}function $t(i,t){return Oe(i,t,"update")}var K={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Mt=new Set(["Write","Edit","NotebookEdit"]),Nt=new Set(["failed","timeout","unavailable"]);function Ut(i){switch(i){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var W=class{constructor(t,e,n){this.projectRoot=t;this.sessionId=e;this.executionId=n;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let n=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(n&&n.expiresAt>Date.now())return "context_ready";n&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new x(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let n=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(n==="context_initializing"&&K[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_INITIALIZING",reason:`DevFlow context initialization is in progress. Wait for ${projectClaudeToolName("get_project_context")} to complete, then retry ${t}.`};if(n==="context_gathering"&&K[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(n==="context_ready"){if(Mt.has(t)){let a=this.evaluateRequiredAction();if(a)return a}return {permissionDecision:"allow"}}let o=K[t];if(!o)return {permissionDecision:"allow"};let r=$t(this.projectRoot,a=>({...a,bypassCount:(a.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,c=Ut(t);return s>=c?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(o)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){Pt(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,n,o){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let c=Date.now(),a=o?.trim()?`${o.trim()}:${e}`:`${t}:${e}:${c}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===a||o&&d.toolUseId===o&&d.status===e)?l:[...l,{id:a,tool:t,status:e,attemptedAt:c,toolUseId:o,reason:n?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?c:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{r?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let n=e.binding;if(n.requiredContextReceipt!==t.contextHash||n.projectRoot!==this.projectRoot||n.sessionId!==this.sessionId||n.requestId!==t.requestId||n.executionId&&n.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:`DevFlow canonical action binding is stale or mismatched. Call ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let o=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&Nt.has(r.status));if(o.length>0){let r=o.at(-1),s={missedTool:e.tool,failedAttemptCount:o.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=n.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!o||o.contextHash!==t.contextHash||o.actionDegradation)return;n.upsertContextReceipt({...o,actionDegradation:e});let r=n.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},c=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];n.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...c,e]}});}catch{}finally{try{n?.close();}catch{}}}};var Yt=10*1024*1024,Kt=5;function Xt(i){return createHash$1("sha256").update(i).digest("hex").slice(0,16)}function Ce(i){return join(homedir(),".devflow","logs","hook-debug",`${Xt(i)}.jsonl`)}function Te(i,t,e={}){let n=e.maxBytes??Yt,o=e.maxFiles??Kt;mkdirSync$1(dirname(i),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:i,maxBytes:n,maxFiles:o,incomingBytes:r}),appendFileSync(i,t,{mode:384}),chmodSync(i,384);}var X="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Fe(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Le(i){let t=i.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function je(i,t){return t?`evt_tool_${createHash("sha256").update(`${i}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var nn=new Set(["Write","Edit","NotebookEdit"]),Pe=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function He(i){if(!nn.has(i.toolName))return null;let t=on(i.toolInput);if(!t)return null;let e=rn(t,i.projectRoot),n=resolve(i.projectRoot,".claude");if($e(e,n)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Pe;let o=resolve(i.home??homedir(),".claude","projects");return $e(e,o)&&relative(o,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Pe:null}function on(i){for(let t of ["file_path","notebook_path","path"]){let e=i[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function rn(i,t){return resolve(isAbsolute(i)?i:resolve(t,i))}function $e(i,t){let e=relative(t,i);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function Be(i){let t=gn(i.toolName,i.toolInput),e=t?fn(i.projectRoot,i.toolName,i.toolInput):void 0;if(!t||!e||!i.toolUseId)return {allowed:true};let n=hn(e),o,r=0,s,c;try{c=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=c.getActiveContextReceipt(i.projectRoot,i.sessionId,i.executionId);o=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(d=>yn(i.projectRoot,d.path,e));}catch{}finally{try{c?.close();}catch{}}let a={toolUseId:i.toolUseId,sessionId:i.sessionId,executionId:i.executionId,operation:t,path:e,before:n,contextReceipt:o,observedAt:Date.now()};if(_n(i.projectRoot,a),t==="edit"||t==="write"||t==="delete"){let l=Rn(i.projectRoot,e),d=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,u=s?.expectedState==="existing"&&!n.exists||s?.expectedState==="missing"&&n.exists||!!(s?.contentHash&&n.hash!==s.contentHash);if(d||s?.expectedState==="existing"&&!n.exists)return qe(i,a,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(u)return qe(i,a,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return Ve(i,a,true),{allowed:true,pending:a}}function qe(i,t,e,n){return Ve(i,t,false,e),{allowed:false,reasonCode:e,reason:n,pending:t}}function Ve(i,t,e,n){D({event:"canonical.action.validated",identity:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:i.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(i.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:n,toolUseId:t.toolUseId}});}function gn(i,t){if(i==="Read")return "read";if(i==="Edit"||i==="NotebookEdit")return "edit";if(i==="Write")return "write";if(i==="Delete"||i==="Bash"&&ze(t.command))return "delete"}function fn(i,t,e){let n=mn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?ze(e.command):void 0);if(!n)return;let o=isAbsolute(n)?normalize(n):resolve(i,n),r=relative(i,o);return r.startsWith("..")||isAbsolute(r)?void 0:o}function ze(i){return typeof i!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(i)?.[2]}function mn(i,t){for(let e of t){let n=i[e];if(typeof n=="string"&&n.trim())return n.trim()}}function hn(i){if(!existsSync$1(i))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(i)).digest("hex")}}catch{return {exists:true}}}function yn(i,t,e){return (isAbsolute(t)?normalize(t):resolve(i,t))===normalize(e)}function Ge(i){return join(w(i),"file-state")}function Ye(i){return join(Ge(i),"pending.json")}function vn(i){return join(Ge(i),"observations.jsonl")}function bn(i){try{return JSON.parse(readFileSync$1(Ye(i),"utf8"))}catch{return {}}}function _n(i,t){let e=Ye(i);mkdirSync$1(dirname(e),{recursive:true});let n=bn(i);n[t.toolUseId]=t,En(e,JSON.stringify(n));}function Rn(i,t){try{let e=readFileSync$1(vn(i),"utf8").trim().split(`
3
- `);for(let n=e.length-1;n>=0;n-=1){let o=JSON.parse(e[n]);if(o.path===t)return o}}catch{}}function En(i,t){let e=`${i}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,i);}var xn=new Set(["delivered","cancelled","rejected"]),kn=new Set(["cancelled","rejected"]),Sn=new Set(["Write","Edit","NotebookEdit","Bash"]);function On(i,t){if(i!=="Bash"||typeof t?.command!="string")return false;let n="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${n}(?: \\|\\| ${n})*$`,"u").test(t.command)}function ne(i,t,e,n,o){if(!Sn.has(e)||!t.trim()||On(e,o))return null;let r=join(i,".devflow","delivery-line","state.db");if(!existsSync$1(r))return null;let s;try{s=new DatabaseSync(r,{readOnly:!0,timeout:250});let c=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),a=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let g of f){let v=[];try{v=JSON.parse(g.aliases);}catch{}(g.source_path===i||v.includes(i))&&a.add(g.case_id);}}let d=[];for(let f of c){let g=JSON.parse(f.payload),v=a.has(f.id);(g.sessionId===t||t===f.id||v)&&d.push({id:f.id,payload:g,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof g.updatedAt=="number"?g.updatedAt:0});let y=typeof g.stage=="string"?g.stage:"unknown";if(!xn.has(y)){if(n&&y==="executing"){let m=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),b=typeof g.sessionId=="string"?g.sessionId:void 0,L=typeof g.executionId=="string"?g.executionId:void 0,O=n===m?.id||n===m?.lease_owner||n===L,B=t===f.id||t===b;if(m?.id&&O&&B)return null}if(g.sessionId===t||t===f.id||v)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:y,message:`Delivery case ${f.id} is ${y}; use the Delivery task lease before modifying files.`}}}let u=d.sort((f,g)=>g.updatedAt-f.updatedAt)[0],p=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&p&&kn.has(p)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:p,message:`Delivery case ${u.id} is ${p}; start a new Delivery case or session before modifying files.`}:null}catch{return {code:"DELIVERY_AUTHORITY_UNAVAILABLE",caseId:"unknown",stage:"unknown",message:"Delivery state cannot be read; file writes are blocked until runtime health is restored."}}finally{s?.close();}}function F(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function ie(i){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:i}}}function Pn(i){let t=w(i);return existsSync(t)||mkdirSync(t,{recursive:true}),t}function $n(i,t,e,n,o,r){let s=join$1(Pn(i),"event-map.json"),c=[];try{existsSync(s)&&(c=JSON.parse(readFileSync(s,"utf-8")));}catch{}c.push({sessionId:t,toolName:e,toolUseId:n,eventId:o,timestamp:r}),writeFileSync(s,JSON.stringify(c));}function Mn(i){switch(i){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function Nn(i,t,e){if(t!=="Read"||typeof e.file_path!="string"||!e.file_path.trim())return null;let n=e.file_path.startsWith("/")?e.file_path:join$1(i,e.file_path);try{if(statSync(n).isDirectory())return `Read accepts files, but "${e.file_path}" is a directory. Use Glob or Bash ls to inspect directory entries, then Read one file.`}catch{return null}return null}function Un(){let i=process.env.CLAUDE_PLUGIN_ROOT;if(!i)return null;let t=join$1(i,"package.json"),e=join$1(i,".mcp.json");try{let n=JSON.parse(readFileSync(t,"utf8")),r=JSON.parse(readFileSync(e,"utf8")).mcpServers?.devflow,s=r?.args;if(r?.command==="node"&&Array.isArray(s)&&s[0]==="${CLAUDE_PLUGIN_ROOT}/node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs")return existsSync(join$1(i,"node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs"))?null:"bundled DevFlow MCP runtime is not installed";let a=Array.isArray(s)?s.indexOf("--package"):-1,l=a>=0&&typeof s?.[a+1]=="string"?s[a+1]:void 0,d=typeof n.version=="string"?`@devflow-tools/mcp-server@${n.version}`:void 0;return l?d&&l!==d?`DevFlow MCP version mismatch (${l} vs ${d})`:null:"DevFlow MCP package configuration is missing"}catch{return "DevFlow MCP configuration could not be inspected"}}function Hn(i,t){return i==="Grep"||i==="Glob"?true:i!=="Bash"||typeof t.command!="string"?false:/^(?:ls|pwd|find|rg|grep|git\s+(?:status|diff|log|branch)|cat|sed|head|tail|wc)\b/u.test(t.command.trim())}async function qn(i){let t=Fe();try{if(!i||i.trim()==="")return F();let e=JSON.parse(i),n=Date.now();try{maybeRunDiagnosticLogCleanup(C(),{now:n});}catch{}let o=C(),r=new N,s=resolveClaudeToolName(e.tool_name,e.tool_input),c=s.status==="unsupported"?void 0:s.canonicalName;c&&(typeof e.tool_input.projectRoot!="string"||!e.tool_input.projectRoot.trim())&&(e.tool_input.projectRoot=o);let a=e.session_id?.trim();if(!a)return ie(X);let l=new x(o),d=l.get(a)!==null;if(l.registerSession(a),d||await r.sendSessionStart(a,o,Date.now()),e.tool_name==="Skill"){let _=e.tool_input?.skill,h=_?Le(_):null;if(h){let R=l.get(a)?.executionId,E=l.startExecution(a,h,he(h));E.executionId&&E.executionId!==R&&await r.sendExecutionStart(E.executionId,a,h,E.lastActivityAt,o,E.requiredMcpTools);}}let u=l.get(a);c==="get_project_context"&&l.beginContextInitialization(a,e.tool_use_id),c&&(e.tool_input._devflow_session_id=a,e.tool_input._devflow_execution_id=u?.executionId??a,u?.activeTurnId&&(e.tool_input._devflow_turn_id=u.activeTurnId),u?.activeRequestId&&(e.tool_input._devflow_request_id=u.activeRequestId),u?.intentArtifactHash&&(e.tool_input._devflow_intent_artifact_hash=u.intentArtifactHash),u?.skillName&&(e.tool_input._devflow_active_skill=u.skillName),e.tool_use_id&&(e.tool_input._devflow_tool_use_id=e.tool_use_id));let p=e.tool_name.startsWith("mcp__"),f=c,g=l.get(a),v=new W(o,a,g?.executionId),y=v.getPhase(),m,b,L=Nn(o,e.tool_name,e.tool_input),O=ne(o,a,e.tool_name,g?.executionId,e.tool_input);if(L)b="DEVFLOW_DIRECTORY_READ_INVALID",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:L}};else if(O)b=O.code,m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${O.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}};else {let _=He({toolName:e.tool_name,toolInput:e.tool_input,projectRoot:o}),h=Be({projectRoot:o,sessionId:a,executionId:g?.executionId,toolUseId:e.tool_use_id,toolName:e.tool_name,toolInput:e.tool_input}),R=_?{permissionDecision:"deny",reason:_}:h.allowed?v.evaluate(e.tool_name,p):{permissionDecision:"deny",reason:h.reason,reasonCode:h.reasonCode},E=R.permissionDecision==="deny"&&!p&&Hn(e.tool_name,e.tool_input)?Un():null;E?(m=ie(`DevFlow MCP is unavailable or stale: ${E}. This read-only fallback is temporary; refresh the plugin installation and call ${projectClaudeToolName("get_project_context")} before editing.`),b=void 0):R.permissionDecision==="deny"?(b=_?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":R.reasonCode??"DEVFLOW_CONTEXT_REQUIRED",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:R.reason??"MCP context required"}}):R.additionalContext?m=ie(R.additionalContext):m=F();}c&&(m.hookSpecificOutput.updatedInput=e.tool_input),t&&m.hookSpecificOutput.permissionDecision==="allow"&&(m.hookSpecificOutput.additionalContext=X);let B=g?.executionId??a,A={eventId:je(a,e.tool_use_id),executionId:B,sessionId:a,projectRoot:o,toolUseId:e.tool_use_id,timestamp:Date.now(),toolName:e.tool_name,toolType:p?"mcp":e.tool_name==="Agent"?"subagent":"direct",isMcpTool:p,mcpToolName:f,mcpEnforced:p&&(y==="context_gathering"||y==="context_initializing"),mcpFallback:!p&&(y==="context_gathering"||y==="context_initializing"),kind:Mn(e.tool_name),input:e.tool_input,duration:0,blocked:m.hookSpecificOutput.permissionDecision==="deny",blockReason:m.hookSpecificOutput.permissionDecision==="deny"?b??"DEVFLOW_CONTEXT_REQUIRED":void 0},j=await r.sendEvent(A);j&&!A.blocked&&$n(o,a,e.tool_name,e.tool_use_id,j,A.timestamp),j&&A.blocked&&await r.completeEvent({eventId:j,sessionId:a,error:b??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-A.timestamp,completedAt:Date.now()});try{let _=Ae(o),h={ts:n,tool:e.tool_name,sessionId:a,skill:u?.skillName??"(none)",requiredTools:u?.requiredMcpTools??[],isMcp:p,enforce:u?.executionId!==void 0,stateless:u?.executionId===void 0&&!p&&e.tool_name!=="Skill",bypassCount:_.bypassCount??0,decision:m.hookSpecificOutput.permissionDecision,env_CLAUDE_PLUGIN_ROOT:process.env.CLAUDE_PLUGIN_ROOT??"(unset)",cwd:process.cwd()};Te(Ce(o),`${JSON.stringify(h)}
4
- `);}catch{}return m}catch{try{let e=JSON.parse(i),n=C(),o=ne(n,String(e.session_id??""),String(e.tool_name??""),void 0,e.tool_input);if(o)return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:o.message}}}catch{}return F()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-tool-use.js")){let i=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await qn(t);i(JSON.stringify(e));}),process.stdin.on("error",()=>{i(JSON.stringify(F())),process.exit(0);}),setTimeout(()=>{i(JSON.stringify(F())),process.exit(0);},4e3).unref();}export{qn as handlePreToolUse};
1
+ import {createHash as createHash$1}from'node:crypto';import {existsSync,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function $(i,t,e){try{let n=openGlobalDevFlowDatabase();try{n.insertEvent({kind:i,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{n.close();}}catch{}}var dt=getLocalApiKey(),G=join(getDevFlowStateRoot(),"errors");async function ce(i,t,e={}){let n=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??ut();if(!n)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),c=e.circuitBreaker??true,a=acquireRuntimeHttpCircuit(n,i);if(c&&!a.allowed)return {delivered:false,suppressed:true,fallbackReason:a.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await pt(n,i,t,o),c&&registerRuntimeHttpSuccess(n,i).transitioned&&$("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await gt(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!c)return se(i,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(n,i,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(se(i,l),$("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:a.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function ut(){let i=readRuntimeState();return i?.status==="ready"&&i.dashboardAvailable?i.url:void 0}function pt(i,t,e,n){return new Promise((o,r)=>{let s=JSON.stringify(e),c=new URL(t,i),a=false,l=u=>{a||(a=true,u?r(u):o());},d=request({hostname:c.hostname,port:c.port,path:c.pathname+c.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":dt,"Content-Length":Buffer.byteLength(s)},timeout:n},u=>{u.on("error",l),u.on("end",()=>{let p=u.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),d.write(s),d.end();})}function se(i,t){try{existsSync$1(G)||mkdirSync$1(G,{recursive:!0});let e=join(G,"http-errors.log"),n=`${new Date().toISOString()} | ${i} | ${t.message}
2
+ `;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(n)}),appendFileSync(e,n);}catch{}}function gt(i){return new Promise(t=>setTimeout(t,i))}var pe=1e4,bt=3e4,U=500,H=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,n,o,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let c={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}async sendExecutionComplete(t,e="completed",n=Date.now(),o){let r={executionId:t,status:e,finishedAt:n,metadata:o},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,n){let o={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",o);return r&&this.postHttp("/api/telemetry/sessions",o),r}async completeEvent(t){let e=this.commitOrCache("complete_event",t);return e&&(this.postHttp("/api/telemetry/tool-call/output",t),this.scheduleMetricAggregation()),e}async endSession(t,e=Date.now()){let n={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",n);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let e=this.getDatabase(),n=e.listTelemetryFailures({unresolvedOnly:!0,limit:U}).reverse();for(let o of n)try{this.applyOperation(o.operation,o.payload),e.resolveTelemetryFailure(o.id);}catch{}e.trimTelemetryFailures(U);}catch{}let t=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let n=join$1(this.cacheDir,e);try{return {cacheFile:n,envelope:_t(JSON.parse(readFileSync(n,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,n)=>e.envelope.timestamp-n.envelope.timestamp||ge(e.envelope.operation)-ge(n.envelope.operation));for(let{cacheFile:e,envelope:n}of t)try{let o=this.getDatabase();o.insertTelemetryFailure({id:n.id,operation:n.operation,payload:n.payload,error:n.failure,createdAt:n.timestamp}),this.applyOperation(n.operation,n.payload),o.resolveTelemetryFailure(n.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(n){return this.cacheOperation(t,e,n),false}}applyOperation(t,e){let n=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(n,e),n.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(n,e),n.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":n.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":n.ensureSession(e),n.insertRun({id:fe(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!n.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":n.closeSession(e.sessionId,e.finishedAt),n.updateRun(fe(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let n=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!n)throw new Error("Canonical session ID is required for telemetry");let o=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:n,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,n){let o=Date.now(),r={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:n instanceof Error?n.message:String(n),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:o}),s.trimTelemetryFailures(U),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-U)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},bt).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){ce(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=pe?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,pe)}...`}}};function ge(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function fe(i){return `hook-run:${i}`}function _t(i){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let t=i;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function T(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(i){return getProjectStateDir(T(i))}var D=emitSemanticControlLog;var kt=2,St=1;function Ot(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function me(i=Ot()){let t=[join$1(i,"dist","command-registry.json"),join$1(i,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let n=JSON.parse(readFileSync(e,"utf8"));if(n.version!==kt&&n.version!==St||!At(n.commands)){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return n.commands}catch(n){D({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:n.message,fallback:"next_registry_candidate"}});}return null}function At(i){return !i||typeof i!="object"||Array.isArray(i)?false:Object.values(i).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return q(e.mcpTools)&&q(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||q(e.runtimePackages))&&(e.hostTools===void 0||Ct(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Ct(i){return !!i&&typeof i=="object"&&!Array.isArray(i)&&Object.entries(i).every(([t,e])=>t.length>0&&q(e))}function q(i){return Array.isArray(i)&&i.every(t=>typeof t=="string"&&t.length>0)}function he(i){let t=me();return t?t[i]?.mcpTools??[]:[]}function _e(i){return Buffer.from(i,"utf8").toString("base64url")}function jt(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function xe(i){return `${i}:legacy-journal`}var S=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(w(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let n=this.get(e);if(n)return n.lastActivityAt=Date.now(),this.persist(n),n;let o=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,n){let o=this.registerSession(t);return (!o.executionId||o.skillName!==e)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=e,o.requiredMcpTools=[...new Set(n)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(t,e){let n=this.registerSession(t);return n.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},n.lastActivityAt=Date.now(),this.persist(n),n}completeContextInitialization(t,e){let n=this.get(t);return n?(e&&n.contextInitialization?.toolUseId&&n.contextInitialization.toolUseId!==e||(delete n.contextInitialization,n.lastActivityAt=Date.now(),this.persist(n)),n):null}bindTaskIdentity(t,e){let n=this.registerSession(t);return n.activeTurnId=e.turnId,n.activeRequestId=e.requestId,n.intentArtifactHash=e.intentArtifactHash,n.lastActivityAt=Date.now(),this.persist(n),n}get(t){let e=t.trim();if(!e)return null;let n=this.sessions.get(e);if(n)return this.replayEvidenceJournal(n),n;let o=this.snapshotPath(e);if(!existsSync(o))return null;try{let r=JSON.parse(readFileSync(o,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=Re(r.evidenceObligations),r.evidenceDegradations=Ee(r.evidenceDegradations),r.evidenceOutcomes=we(r.evidenceOutcomes),this.replayEvidenceJournal(r),this.sessions.set(e,r),r)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let n=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),c=(o?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??jt(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:c,contractId:e.id,at:n,contract:e},`add\0${c}`),this.replayEvidenceJournal(r);let a=r.evidenceObligations.find(l=>l.obligationId===c);return a?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(a)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,n,o,r=Date.now()){let s=this.get(t),c=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!c)return null;let a=/^[a-f0-9]{64}$/.test(o)?o:"";if(!a)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:c.contractId,at:r,fingerprint:a,violations:n.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${a}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let n=this.get(t);if(!n)return false;let o=n.evidenceObligations.find(s=>s.obligationId===e);if(!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}resolveDegradedEvidence(t,e){let n=this.get(t),o=n?.evidenceDegradations.find(s=>s.obligationId===e);if(!n||!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(n),n.lastActivityAt=r,this.persist(n),true}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(a=>a.obligationId===e);if(!r||!s)return false;let c=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:c},`degrade\0${e}\0${c}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${_e(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",_e(t))}appendEvidenceEvent(t,e,n){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let r=createHash("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync(s))return;let c=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(c,JSON.stringify(e),{mode:384});try{linkSync(c,s);}catch(a){if(a.code!=="EEXIST")throw a}finally{rmSync(c,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Re(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=we(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let n;try{n=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let o=n.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let c=Pt(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||De(r.kind)-De(s.kind));for(let r of o)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let n=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(n)return;let s=t.evidenceObligations.find(c=>c.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||n||o.correctionFingerprint===e.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=e.at,o.correctionFingerprint=e.fingerprint,o.violations=e.violations;return}let r=o?.attempt??n?.attempt??0;if(e.kind==="resolve"&&n?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(n)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(n,JSON.stringify(t),{mode:384}),renameSync(n,e);}};function Re(i){return Array.isArray(i)?i.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!ke(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:xe(e.contractId),o=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??o;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:n,correctionFingerprint:r}]}).slice(-8):[]}function Ee(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function we(i){return Array.isArray(i)?i.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function Pt(i){if(!i||typeof i!="object")return null;let t=i,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:xe(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return ke(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let r=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function De(i){return i==="add"?0:i==="correction"?1:2}function ke(i){if(!i||typeof i!="object")return false;let t=i,e=t.requiredSections,n=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(n)&&n.length<=16&&n.every(o=>typeof o=="string"&&o.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}function J(i){if(!i||typeof i!="object"||Array.isArray(i))return {};let t=i,e={};for(let n of ["lastMcpCall","bypassCount"])if(n in t){let o=t[n];if(o==null)continue;e[n]=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;}return e}function Mt(i,t){return i.lastMcpCall===t.lastMcpCall&&i.bypassCount===t.bypassCount}function Se(i,t,e){let n=e instanceof Error?e.message:String(e);D({event:"hook.runtime.degraded",identity:{projectRoot:i},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:n,fallback:"fail_open"}});}function Oe(i,t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o={},r=n.updateHookReceipt(i,c=>(o=J(c),J(t(o)))),s=J(r);return {receipt:s,applied:!0,changed:!Mt(o,s)}}catch(o){return Se(i,e,o),{receipt:{},applied:false,changed:false}}finally{try{n?.close();}catch{}}}function Ae(i){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),J(t.getHookReceipt(i))}catch(e){return Se(i,"update",e),{}}finally{try{t?.close();}catch{}}}function $t(i,t){return Oe(i,()=>t,"write").applied}function Nt(i,t){return Oe(i,t,"update")}var Q={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Ut=new Set(["Write","Edit","NotebookEdit"]),Ht=new Set(["failed","timeout","unavailable"]);function qt(i){switch(i){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var B=class{constructor(t,e,n){this.projectRoot=t;this.sessionId=e;this.executionId=n;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let n=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(n&&n.expiresAt>Date.now())return "context_ready";n&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new S(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let n=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(n==="context_initializing"&&Q[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_INITIALIZING",reason:`DevFlow context initialization is in progress. Wait for ${projectClaudeToolName("get_project_context")} to complete, then retry ${t}.`};if(n==="context_gathering"&&Q[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call ${projectClaudeToolName("get_project_context")}, then retry ${t}.`};if(n==="context_ready"){if(Ut.has(t)){let a=this.evaluateRequiredAction();if(a)return a}return {permissionDecision:"allow"}}let o=Q[t];if(!o)return {permissionDecision:"allow"};let r=Nt(this.projectRoot,a=>({...a,bypassCount:(a.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,c=qt(t);return s>=c?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(o)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){$t(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,n,o){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let c=Date.now(),a=o?.trim()?`${o.trim()}:${e}`:`${t}:${e}:${c}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===a||o&&d.toolUseId===o&&d.status===e)?l:[...l,{id:a,tool:t,status:e,attemptedAt:c,toolUseId:o,reason:n?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?c:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{r?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let n=e.binding;if(n.requiredContextReceipt!==t.contextHash||n.projectRoot!==this.projectRoot||n.sessionId!==this.sessionId||n.requestId!==t.requestId||n.executionId&&n.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:`DevFlow canonical action binding is stale or mismatched. Call ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let o=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&Ht.has(r.status));if(o.length>0){let r=o.at(-1),s={missedTool:e.tool,failedAttemptCount:o.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let n;try{n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=n.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!o||o.contextHash!==t.contextHash||o.actionDegradation)return;n.upsertContextReceipt({...o,actionDegradation:e});let r=n.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},c=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];n.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...c,e]}});}catch{}finally{try{n?.close();}catch{}}}};var Xt=10*1024*1024,Qt=5;function Zt(i){return createHash$1("sha256").update(i).digest("hex").slice(0,16)}function Ce(i){return join(homedir(),".devflow","logs","hook-debug",`${Zt(i)}.jsonl`)}function Te(i,t,e={}){let n=e.maxBytes??Xt,o=e.maxFiles??Qt;mkdirSync$1(dirname(i),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:i,maxBytes:n,maxFiles:o,incomingBytes:r}),appendFileSync(i,t,{mode:384}),chmodSync(i,384);}var Z="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Fe(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Le(i){let t=i.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function je(i,t){return t?`evt_tool_${createHash("sha256").update(`${i}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var rn=new Set(["Write","Edit","NotebookEdit"]),Pe=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function He(i){if(!rn.has(i.toolName))return null;let t=sn(i.toolInput);if(!t)return null;let e=an(t,i.projectRoot),n=resolve(i.projectRoot,".claude");if(Me(e,n)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Pe;let o=resolve(i.home??homedir(),".claude","projects");return Me(e,o)&&relative(o,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Pe:null}function sn(i){for(let t of ["file_path","notebook_path","path"]){let e=i[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function an(i,t){return resolve(isAbsolute(i)?i:resolve(t,i))}function Me(i,t){let e=relative(t,i);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function Be(i){let t=mn(i.toolName,i.toolInput),e=t?hn(i.projectRoot,i.toolName,i.toolInput):void 0;if(!t||!e||!i.toolUseId)return {allowed:true};let n=vn(e),o,r=0,s,c;try{c=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=c.getActiveContextReceipt(i.projectRoot,i.sessionId,i.executionId);o=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(d=>bn(i.projectRoot,d.path,e));}catch{}finally{try{c?.close();}catch{}}let a={toolUseId:i.toolUseId,sessionId:i.sessionId,executionId:i.executionId,operation:t,path:e,before:n,contextReceipt:o,observedAt:Date.now()};if(En(i.projectRoot,a),t==="edit"||t==="write"||t==="delete"){let l=wn(i.projectRoot,e),d=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,u=s?.expectedState==="existing"&&!n.exists||s?.expectedState==="missing"&&n.exists||!!(s?.contentHash&&n.hash!==s.contentHash);if(d||s?.expectedState==="existing"&&!n.exists)return qe(i,a,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(u)return qe(i,a,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return Ve(i,a,true),{allowed:true,pending:a}}function qe(i,t,e,n){return Ve(i,t,false,e),{allowed:false,reasonCode:e,reason:n,pending:t}}function Ve(i,t,e,n){D({event:"canonical.action.validated",identity:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:i.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(i.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:n,toolUseId:t.toolUseId}});}function mn(i,t){if(i==="Read")return "read";if(i==="Edit"||i==="NotebookEdit")return "edit";if(i==="Write")return "write";if(i==="Delete"||i==="Bash"&&ze(t.command))return "delete"}function hn(i,t,e){let n=yn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?ze(e.command):void 0);if(!n)return;let o=isAbsolute(n)?normalize(n):resolve(i,n),r=relative(i,o);return r.startsWith("..")||isAbsolute(r)?void 0:o}function ze(i){return typeof i!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(i)?.[2]}function yn(i,t){for(let e of t){let n=i[e];if(typeof n=="string"&&n.trim())return n.trim()}}function vn(i){if(!existsSync$1(i))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(i)).digest("hex")}}catch{return {exists:true}}}function bn(i,t,e){return (isAbsolute(t)?normalize(t):resolve(i,t))===normalize(e)}function Ge(i){return join(w(i),"file-state")}function Ye(i){return join(Ge(i),"pending.json")}function _n(i){return join(Ge(i),"observations.jsonl")}function Rn(i){try{return JSON.parse(readFileSync$1(Ye(i),"utf8"))}catch{return {}}}function En(i,t){let e=Ye(i);mkdirSync$1(dirname(e),{recursive:true});let n=Rn(i);n[t.toolUseId]=t,Dn(e,JSON.stringify(n));}function wn(i,t){try{let e=readFileSync$1(_n(i),"utf8").trim().split(`
3
+ `);for(let n=e.length-1;n>=0;n-=1){let o=JSON.parse(e[n]);if(o.path===t)return o}}catch{}}function Dn(i,t){let e=`${i}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,i);}var Sn=new Set(["delivered","cancelled","rejected"]),On=new Set(["cancelled","rejected"]),An=new Set(["Write","Edit","NotebookEdit","Bash"]);function Cn(i,t){if(i!=="Bash"||typeof t?.command!="string")return false;let n="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${n}(?: \\|\\| ${n})*$`,"u").test(t.command)}function oe(i,t,e,n,o){if(e.includes("delivery_rebind_session")||!An.has(e)||!t.trim()||Cn(e,o))return null;let r=join(i,".devflow","delivery-line","state.db");if(!existsSync$1(r))return null;let s;try{s=new DatabaseSync(r,{readOnly:!0,timeout:250});let c=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),a=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let g of f){let b=[];try{b=JSON.parse(g.aliases);}catch{}(g.source_path===i||b.includes(i))&&a.add(g.case_id);}}let d=[];for(let f of c){let g=JSON.parse(f.payload),b=a.has(f.id);(g.sessionId===t||t===f.id||b)&&d.push({id:f.id,payload:g,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof g.updatedAt=="number"?g.updatedAt:0});let y=typeof g.stage=="string"?g.stage:"unknown";if(!Sn.has(y)){if(n&&y==="executing"){let m=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),v=typeof g.sessionId=="string"?g.sessionId:void 0,j=typeof g.executionId=="string"?g.executionId:void 0,x=n===m?.id||n===m?.lease_owner||n===j,P=t===f.id||t===v;if(m?.id&&x&&P)return null}if(g.sessionId===t||t===f.id||b)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:y,message:`Delivery case ${f.id} is ${y}; use the Delivery task lease before modifying files.`}}}let u=d.sort((f,g)=>g.updatedAt-f.updatedAt)[0],p=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&p&&On.has(p)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:p,message:`Delivery case ${u.id} is ${p}; start a new Delivery case or session before modifying files.`}:null}catch{return {code:"DELIVERY_AUTHORITY_UNAVAILABLE",caseId:"unknown",stage:"unknown",message:"Delivery state cannot be read; file writes are blocked until runtime health is restored."}}finally{s?.close();}}function F(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function re(i){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:i}}}function Nn(i){let t=w(i);return existsSync(t)||mkdirSync(t,{recursive:true}),t}function Un(i,t,e,n,o,r){let s=join$1(Nn(i),"event-map.json"),c=[];try{existsSync(s)&&(c=JSON.parse(readFileSync(s,"utf-8")));}catch{}c.push({sessionId:t,toolName:e,toolUseId:n,eventId:o,timestamp:r}),writeFileSync(s,JSON.stringify(c));}function Hn(i){switch(i){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function qn(i,t,e){if(t!=="Read"||typeof e.file_path!="string"||!e.file_path.trim())return null;let n=e.file_path.startsWith("/")?e.file_path:join$1(i,e.file_path);try{if(statSync(n).isDirectory())return `Read accepts files, but "${e.file_path}" is a directory. Use Glob or Bash ls to inspect directory entries, then Read one file.`}catch{return null}return null}function Wn(){let i=process.env.CLAUDE_PLUGIN_ROOT;if(!i)return null;let t=join$1(i,"package.json"),e=join$1(i,".mcp.json");try{let n=JSON.parse(readFileSync(t,"utf8")),r=JSON.parse(readFileSync(e,"utf8")).mcpServers?.devflow,s=r?.args;if(r?.command==="node"&&Array.isArray(s)&&s[0]==="${CLAUDE_PLUGIN_ROOT}/node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs")return existsSync(join$1(i,"node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs"))?null:"bundled DevFlow MCP runtime is not installed";let a=Array.isArray(s)?s.indexOf("--package"):-1,l=a>=0&&typeof s?.[a+1]=="string"?s[a+1]:void 0,d=typeof n.version=="string"?`@devflow-tools/mcp-server@${n.version}`:void 0;return l?d&&l!==d?`DevFlow MCP version mismatch (${l} vs ${d})`:null:"DevFlow MCP package configuration is missing"}catch{return "DevFlow MCP configuration could not be inspected"}}function Jn(){let i=process.env.CLAUDE_PLUGIN_ROOT?.trim();if(!i)return null;try{let t=join$1(i,"dist","runtime-manifest.json"),e=JSON.parse(readFileSync(t,"utf8")),n=typeof e.bundleHashes?.mcp=="string"?e.bundleHashes.mcp:void 0,o=join$1(i,"node_modules","@devflow-tools","mcp-server","dist","delivery-tools.js"),r=existsSync(o)?createHash$1("sha256").update(readFileSync(o)).digest("hex"):"missing";return !n||n!==r?"DevFlow runtime build does not match the active plugin manifest":null}catch{return "DevFlow runtime manifest is missing or invalid"}}function Bn(i,t,e){return new Set(["Write","Edit","NotebookEdit"]).has(i)?true:i==="Bash"?!Ke(i,t):!!(e?.startsWith("delivery_")&&e!=="delivery_status")}function Ke(i,t){return i==="Grep"||i==="Glob"?true:i!=="Bash"||typeof t.command!="string"?false:/^(?:ls|pwd|find|rg|grep|git\s+(?:status|diff|log|branch)|cat|sed|head|tail|wc)\b/u.test(t.command.trim())}async function Vn(i){let t=Fe();try{if(!i||i.trim()==="")return F();let e=JSON.parse(i),n=Date.now();try{maybeRunDiagnosticLogCleanup(T(),{now:n});}catch{}let o=T(),r=new H,s=resolveClaudeToolName(e.tool_name,e.tool_input),c=s.status==="unsupported"?void 0:s.canonicalName;c&&(typeof e.tool_input.projectRoot!="string"||!e.tool_input.projectRoot.trim())&&(e.tool_input.projectRoot=o);let a=e.session_id?.trim();if(!a)return re(Z);let l=new S(o),d=l.get(a)!==null;if(l.registerSession(a),d||await r.sendSessionStart(a,o,Date.now()),e.tool_name==="Skill"){let _=e.tool_input?.skill,h=_?Le(_):null;if(h){let R=l.get(a)?.executionId,E=l.startExecution(a,h,he(h));E.executionId&&E.executionId!==R&&await r.sendExecutionStart(E.executionId,a,h,E.lastActivityAt,o,E.requiredMcpTools);}}let u=l.get(a);c==="get_project_context"&&l.beginContextInitialization(a,e.tool_use_id),c&&(e.tool_input._devflow_session_id=a,e.tool_input._devflow_execution_id=u?.executionId??a,u?.activeTurnId&&(e.tool_input._devflow_turn_id=u.activeTurnId),u?.activeRequestId&&(e.tool_input._devflow_request_id=u.activeRequestId),u?.intentArtifactHash&&(e.tool_input._devflow_intent_artifact_hash=u.intentArtifactHash),u?.skillName&&(e.tool_input._devflow_active_skill=u.skillName),e.tool_use_id&&(e.tool_input._devflow_tool_use_id=e.tool_use_id));let p=e.tool_name.startsWith("mcp__"),f=c,g=l.get(a),b=new B(o,a,g?.executionId),y=b.getPhase(),m,v,j=qn(o,e.tool_name,e.tool_input),x=oe(o,a,e.tool_name,g?.executionId,e.tool_input),P=!x&&Bn(e.tool_name,e.tool_input,f)?Jn():null;if(P)v="DEVFLOW_RUNTIME_VERSION_MISMATCH",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${P}. Update or restart the DevFlow plugin before approving, executing, or modifying files.`}};else if(j)v="DEVFLOW_DIRECTORY_READ_INVALID",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:j}};else if(x)v=x.code,m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${x.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}};else {let _=He({toolName:e.tool_name,toolInput:e.tool_input,projectRoot:o}),h=Be({projectRoot:o,sessionId:a,executionId:g?.executionId,toolUseId:e.tool_use_id,toolName:e.tool_name,toolInput:e.tool_input}),R=_?{permissionDecision:"deny",reason:_}:h.allowed?b.evaluate(e.tool_name,p):{permissionDecision:"deny",reason:h.reason,reasonCode:h.reasonCode},E=R.permissionDecision==="deny"&&!p&&Ke(e.tool_name,e.tool_input)?Wn():null;E?(m=re(`DevFlow MCP is unavailable or stale: ${E}. This read-only fallback is temporary; refresh the plugin installation and call ${projectClaudeToolName("get_project_context")} before editing.`),v=void 0):R.permissionDecision==="deny"?(v=_?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":R.reasonCode??"DEVFLOW_CONTEXT_REQUIRED",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:R.reason??"MCP context required"}}):R.additionalContext?m=re(R.additionalContext):m=F();}c&&(m.hookSpecificOutput.updatedInput=e.tool_input),t&&m.hookSpecificOutput.permissionDecision==="allow"&&(m.hookSpecificOutput.additionalContext=Z);let Xe=g?.executionId??a,C={eventId:je(a,e.tool_use_id),executionId:Xe,sessionId:a,projectRoot:o,toolUseId:e.tool_use_id,timestamp:Date.now(),toolName:e.tool_name,toolType:p?"mcp":e.tool_name==="Agent"?"subagent":"direct",isMcpTool:p,mcpToolName:f,mcpEnforced:p&&(y==="context_gathering"||y==="context_initializing"),mcpFallback:!p&&(y==="context_gathering"||y==="context_initializing"),kind:Hn(e.tool_name),input:e.tool_input,duration:0,blocked:m.hookSpecificOutput.permissionDecision==="deny",blockReason:m.hookSpecificOutput.permissionDecision==="deny"?v??"DEVFLOW_CONTEXT_REQUIRED":void 0},M=await r.sendEvent(C);M&&!C.blocked&&Un(o,a,e.tool_name,e.tool_use_id,M,C.timestamp),M&&C.blocked&&await r.completeEvent({eventId:M,sessionId:a,error:v??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-C.timestamp,completedAt:Date.now()});try{let _=Ae(o),h={ts:n,tool:e.tool_name,sessionId:a,skill:u?.skillName??"(none)",requiredTools:u?.requiredMcpTools??[],isMcp:p,enforce:u?.executionId!==void 0,stateless:u?.executionId===void 0&&!p&&e.tool_name!=="Skill",bypassCount:_.bypassCount??0,decision:m.hookSpecificOutput.permissionDecision,env_CLAUDE_PLUGIN_ROOT:process.env.CLAUDE_PLUGIN_ROOT??"(unset)",cwd:process.cwd()};Te(Ce(o),`${JSON.stringify(h)}
4
+ `);}catch{}return m}catch{try{let e=JSON.parse(i),n=T(),o=oe(n,String(e.session_id??""),String(e.tool_name??""),void 0,e.tool_input);if(o)return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:o.message}}}catch{}return F()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-tool-use.js")){let i=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await Vn(t);i(JSON.stringify(e));}),process.stdin.on("error",()=>{i(JSON.stringify(F())),process.exit(0);}),setTimeout(()=>{i(JSON.stringify(F())),process.exit(0);},4e3).unref();}export{Vn as handlePreToolUse};
@@ -1,4 +1,4 @@
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}
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 Le=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Ne();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 Ne(){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":Le,"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
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(`
3
3
 
4
4
  ---
@@ -7,7 +7,7 @@ import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,acquireRuntimeH
7
7
 
8
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
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})
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 N(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)&&N(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||!N(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:N(o.memoryIds,ge)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function L(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=L(o.family,"unknown"),i=L(o.entity,"unknown"),s=L(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})
11
11
  ${t.join(`
12
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
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(`
@@ -28,6 +28,21 @@ fi
28
28
  source "${PLUGIN_ROOT}/hooks/runtime-node"
29
29
  DEVFLOW_NODE="$(devflow_resolve_node "$PLUGIN_ROOT")"
30
30
 
31
+ # The registry points at an immutable build directory. Verify that this
32
+ # session loaded the build currently selected by the atomic active pointer.
33
+ ACTIVE_POINTER="$(dirname "$PLUGIN_ROOT")/active.json"
34
+ PLUGIN_VERSION_STATUS="ready"
35
+ if [ -f "$ACTIVE_POINTER" ] && command -v python3 >/dev/null 2>&1; then
36
+ PLUGIN_VERSION_STATUS=$(PLUGIN_ROOT="$PLUGIN_ROOT" ACTIVE_POINTER="$ACTIVE_POINTER" python3 -c 'import json,os
37
+ try:
38
+ active=json.load(open(os.environ["ACTIVE_POINTER"]))
39
+ loaded=os.path.realpath(os.environ["PLUGIN_ROOT"])
40
+ selected=os.path.realpath(str(active.get("installPath", "")))
41
+ print("ready" if selected == loaded else "mismatch")
42
+ except Exception:
43
+ print("invalid")' 2>/dev/null || echo "invalid")
44
+ fi
45
+
31
46
  # Read DevFlow Constitution from file (avoids shell escaping issues)
32
47
  CONSTITUTION_FILE="${PLUGIN_ROOT}/skills/devflow/SKILL.md"
33
48
  if [ -f "${PLUGIN_ROOT}/hooks/constitution.md" ]; then
@@ -69,7 +84,7 @@ if [ -x "$DEVFLOW_NODE" ] && [ -f "$MCP_SERVER_BIN" ]; then
69
84
  MCP_HEALTH_JSON=$("$DEVFLOW_NODE" "$MCP_SERVER_BIN" --healthcheck 2>/dev/null || true)
70
85
  if [ -n "$MCP_HEALTH_JSON" ] && command -v python3 >/dev/null 2>&1; then
71
86
  MCP_HEALTH_STATUS=$(printf '%s' "$MCP_HEALTH_JSON" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('status','failed'))" 2>/dev/null || echo "failed")
72
- MCP_HEALTH_DETAIL=$(printf '%s' "$MCP_HEALTH_JSON" | python3 -c "import json,sys; d=json.load(sys.stdin); print('toolCount=%s serverVersion=%s' % (d.get('toolCount','?'), d.get('serverInfoVersion') or '?'))" 2>/dev/null || true)
87
+ MCP_HEALTH_DETAIL=$(printf '%s' "$MCP_HEALTH_JSON" | python3 -c "import json,sys; d=json.load(sys.stdin); m=d.get('runtimeManifestMatch'); suffix='' if m in (None,True) else ' runtimeManifest=stale'; print('toolCount=%s serverVersion=%s%s' % (d.get('toolCount','?'), d.get('serverInfoVersion') or '?', suffix))" 2>/dev/null || true)
73
88
  else
74
89
  MCP_HEALTH_STATUS="failed"
75
90
  MCP_HEALTH_DETAIL="healthcheck returned no result"
@@ -80,6 +95,12 @@ fi
80
95
 
81
96
  # Append Gateway status to summary
82
97
  GATEWAY_STATUS=$'\n\n━━━━━━ DevFlow Gateway ━━━━━━\n'
98
+ if [ "$PLUGIN_VERSION_STATUS" != "ready" ]; then
99
+ GATEWAY_STATUS="${GATEWAY_STATUS}⚠️ DevFlow 插件缓存版本校验失败(${PLUGIN_VERSION_STATUS}):当前 session 未加载 active 构建。请更新/重启 DevFlow 后再执行审批或写入操作。"$'\n'
100
+ fi
101
+ if [ "$MCP_HEALTH_STATUS" != "ready" ]; then
102
+ GATEWAY_STATUS="${GATEWAY_STATUS}⚠️ DevFlow runtime 校验失败:当前插件与 MCP 运行时可能不是同一构建。请更新/重启 DevFlow 后再执行审批或写入操作。"$'\n'
103
+ fi
83
104
  # Check if devflow MCP server is configured (token will be auto-generated by ensureSessionToken)
84
105
  if [ -f "$PLUGIN_ROOT/.mcp.json" ] && grep -q '"devflow"' "$PLUGIN_ROOT/.mcp.json" 2>/dev/null; then
85
106
  GATEWAY_STATUS="${GATEWAY_STATUS}Status: server=${MCP_HEALTH_STATUS} DevFlow MCP 已配置(插件级)"$'\n'"${MCP_HEALTH_DETAIL}"$'\n'"Gate 层数: ${GATE_COUNT} (${GATE_DETAIL})"$'\n'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.18.62",
3
+ "version": "0.18.64",
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.62",
16
- "@devflow-tools/context-engine": "0.18.62",
17
- "@devflow-tools/database": "0.18.62",
18
- "@devflow-tools/mcp-server": "0.18.62",
19
- "@devflow-tools/memory-engine": "0.18.62",
20
- "@devflow-tools/sdk": "0.18.62",
21
- "@devflow-tools/semantic-engine": "0.18.62",
22
- "@devflow-tools/server": "0.18.62",
23
- "@devflow-tools/task-runtime": "0.18.62",
24
- "@devflow-tools/telemetry": "0.18.62",
25
- "@devflow-tools/workflow-engine": "0.18.62"
15
+ "@devflow-tools/benchmark": "0.18.64",
16
+ "@devflow-tools/context-engine": "0.18.64",
17
+ "@devflow-tools/database": "0.18.64",
18
+ "@devflow-tools/mcp-server": "0.18.64",
19
+ "@devflow-tools/memory-engine": "0.18.64",
20
+ "@devflow-tools/sdk": "0.18.64",
21
+ "@devflow-tools/semantic-engine": "0.18.64",
22
+ "@devflow-tools/server": "0.18.64",
23
+ "@devflow-tools/task-runtime": "0.18.64",
24
+ "@devflow-tools/telemetry": "0.18.64",
25
+ "@devflow-tools/workflow-engine": "0.18.64"
26
26
  },
27
27
  "devDependencies": {
28
- "@devflow-tools/devflow": "0.18.62"
28
+ "@devflow-tools/devflow": "0.18.64"
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": "654d69dc9c28951200816a047689e72a056bfa58",
54
54
  "license": "MIT",
55
55
  "repository": {
56
56
  "type": "git",