@devflow-tools/cli 0.16.32 → 0.16.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +5 -5
- package/dist/plugin-files/dist/hooks/hook-daemon.js +22 -22
- package/dist/plugin-files/dist/hooks/post-tool-use.js +3 -3
- package/dist/plugin-files/dist/hooks/session-end.js +4 -4
- package/dist/plugin-files/package.json +10 -10
- package/package.json +27 -27
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {getLogWriter}from'@devflow-tools/telemetry';import {request}from'node:http';import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,appendFileSync,readFileSync as readFileSync$1,readdirSync as readdirSync$1}from'node:fs';import {join,resolve,isAbsolute,relative,sep}from'node:path';import {homedir}from'node:os';import {getLocalApiKey,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir}from'@devflow-tools/sdk';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {homedir as homedir$1}from'os';import {randomUUID,createHash}from'crypto';import {fileURLToPath}from'url';import {createHash as createHash$1}from'node:crypto';import {classifyWorkflowFailure}from'@devflow-tools/workflow-engine/failure-classifier';function H(n,t,e){try{let i=openGlobalDevFlowDatabase();try{i.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{i.close();}}catch{}}var et=getLocalApiKey(),U=join(homedir(),".devflow","errors");async function D(n,t,e={}){let i=e.endpoint??resolveRuntimeEndpoint().url,r=e.timeout??1500,o=e.durableMirror??true,s=e.maxRetries??(o?0:2),a=e.circuitBreaker??true,c=acquireRuntimeHttpCircuit(i,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 tt(i,n,t,r),a&®isterRuntimeHttpSuccess(i,n).transitioned&&H("http_circuit_transition",{endpoint:i,path:new URL(n,i).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await nt(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return de(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(i,n,e.fallbackReason??(o?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(de(n,l),H("http_circuit_transition",{endpoint:i,path:new URL(n,i).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 tt(n,t,e,i){return new Promise((r,o)=>{let s=JSON.stringify(e),a=new URL(t,n),c=false,l=u=>{c||(c=true,u?o(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":et,"Content-Length":Buffer.byteLength(s)},timeout:i},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 ${i}ms`))),d.write(s),d.end();})}function de(n,t){try{existsSync$1(U)||mkdirSync$1(U,{recursive:!0}),appendFileSync(join(U,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${t.message}
|
|
2
|
-
`);}catch{}}function nt(n){return new Promise(t=>setTimeout(t,n))}function z(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function y(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(z(n))}function C(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let t=n,e={};for(let i of ["lastMcpCall","bypassCount"])if(i in t){let r=t[i];if(r==null)continue;e[i]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return e}function st(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function at(n){try{return existsSync(n)?C(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function ct(n,t){let e=t instanceof Error?t.message:String(t);console.error(`[devflow] Receipt ${n} skipped: ${e}`);}function pe(n){let t=y(n);for(let e of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync(join$1(t,e))&&unlinkSync(join$1(t,e));}catch{}}function lt(n,t){if(n.getHookReceipt(t)){pe(t);return}let e=join$1(y(t),"receipt.json");if(!existsSync(e))return;let i=at(e);n.updateHookReceipt(t,()=>i),pe(t);}function ge(n,t,e){let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),lt(i,n);let r={},o=i.updateHookReceipt(n,a=>(r=C(a),C(t(r)))),s=C(o);return {receipt:s,applied:!0,changed:!st(r,s)}}catch(r){return ct(e,r),{receipt:{},applied:false,changed:false}}finally{try{i?.close();}catch{}}}function J(n,t){return ge(n,()=>t,"write").applied}function B(n,t){return ge(n,t,"update")}var fe={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},dt=new Set(["Write","Edit","NotebookEdit"]),ut=new Set(["failed","timeout","unavailable"]);function pt(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var O=class{constructor(t,e,i){this.projectRoot=t;this.sessionId=e;this.executionId=i;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(e&&e.expiresAt>Date.now())return "context_ready";e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}return "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 i=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(i==="context_gathering"&&fe[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${t}.`};if(i==="context_ready"){if(dt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let r=fe[t];if(!r)return {permissionDecision:"allow"};let o=B(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!o.applied)return {permissionDecision:"allow"};let s=o.receipt.bypassCount??0,a=pt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){J(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,i,r){if(!this.sessionId||!this.executionId)return false;let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=o.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=r?.trim()?`${r.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return o.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||r&&d.toolUseId===r&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:r,reason:i?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?a:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{o?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let i=e.binding;if(i.requiredContextReceipt!==t.contextHash||i.projectRoot!==this.projectRoot||i.sessionId!==this.sessionId||i.requestId!==t.requestId||i.executionId&&i.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:"DevFlow canonical action binding is stale or mismatched. Call mcp__devflow__get_project_context again before writing."};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let r=(t.actionAttempts??[]).filter(o=>o.tool===e.tool&&ut.has(o.status));if(r.length>0){let o=r.at(-1),s={missedTool:e.tool,failedAttemptCount:r.length,reason:`${o.status}:${o.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool mcp__devflow__${e.tool} ${o.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 mcp__devflow__${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 i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r=i.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!r||r.contextHash!==t.contextHash||r.actionDegradation)return;i.upsertContextReceipt({...r,actionDegradation:e});let o=i.getSkillExecution(t.executionId);if(!o)return;let s=o.metadata&&typeof o.metadata=="object"?o.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];i.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...o.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(o.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(o.fallbackCount??0)+1,fallbackReasons:[...new Set([...o.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{i?.close();}catch{}}}};var ve=1e4,ht=3e4,T=500,$=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","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,i,r,o=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:i,startedAt:r,projectRoot:o,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",i=Date.now(),r){let o={executionId:t,status:e,finishedAt:i,metadata:r},s=this.commitOrCache("execution_complete",o);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",o),s}async sendSessionStart(t,e,i){let r={id:t,projectRoot:e,startedAt:i,label:e.split("/").pop()??"unknown"},o=this.commitOrCache("session_start",r);return o&&this.postHttp("/api/telemetry/sessions",r),o}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 i={sessionId:t,finishedAt:e},r=this.commitOrCache("session_end",i);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),r}async flushCache(){try{let i=this.getDatabase(),r=i.listTelemetryFailures({unresolvedOnly:!0,limit:T}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),i.resolveTelemetryFailure(o.id);}catch{}i.trimTelemetryFailures(T);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(i=>!!i))].filter(i=>existsSync(i)).flatMap(i=>readdirSync(i).filter(r=>r.endsWith(".json")).map(r=>{let o=join$1(i,r);try{return {cacheFile:o,envelope:bt(JSON.parse(readFileSync(o,"utf8")),r)}}catch{return null}})).filter(i=>i!==null).sort((i,r)=>i.envelope.timestamp-r.envelope.timestamp||Re(i.envelope.operation)-Re(r.envelope.operation));for(let{cacheFile:i,envelope:r}of e)try{let o=this.getDatabase();o.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),o.resolveTelemetryFailure(r.id),unlinkSync(i);}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(i){return this.cacheOperation(t,e,i),false}}applyOperation(t,e){let i=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(i,e),i.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(i,e),i.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":i.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":i.ensureSession(e),i.insertRun({id:we(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(!i.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":i.closeSession(e.sessionId,e.finishedAt),i.updateRun(we(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let i=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!i)throw new Error("Canonical session ID is required for telemetry");let r=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:i,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,i){let r=Date.now(),o={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:i instanceof Error?i.message:String(i),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:o.id,operation:t,payload:e,error:o.failure,createdAt:r}),s.trimTelemetryFailures(T),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(o,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-T)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},ht).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){D(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ve?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ve)}...`}}};function Re(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function we(n){return `hook-run:${n}`}function bt(n,t){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let i=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!i)throw new Error("Unknown legacy telemetry cache operation");let r=e.payload??{},o=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:i,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:o}}function ke(n){return Buffer.from(n,"utf8").toString("base64url")}function _t(n,t,e){let i=t?.trim();if(i){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(i)?i:`tool-${createHash("sha256").update(i.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Oe(n){return `${n}:legacy-journal`}var k=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(y(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let i=this.get(e);if(i)return i.lastActivityAt=Date.now(),this.persist(i),i;let r=Date.now(),o={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(e,o),this.persist(o),o}startExecution(t,e,i){let r=this.registerSession(t);return (!r.executionId||r.skillName!==e)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=e,r.requiredMcpTools=[...new Set(i)],r.lastActivityAt=Date.now(),this.persist(r),r}get(t){let e=t.trim();if(!e)return null;let i=this.sessions.get(e);if(i)return this.replayEvidenceJournal(i),i;let r=this.snapshotPath(e);if(!existsSync(r))return null;try{let o=JSON.parse(readFileSync(r,"utf8"));return o.sessionId!==e||o.projectRoot!==this.projectRoot?null:(o.requiredMcpTools=Array.isArray(o.requiredMcpTools)?o.requiredMcpTools:[],o.evidenceObligations=Ee(o.evidenceObligations),o.evidenceDegradations=Se(o.evidenceDegradations),o.evidenceOutcomes=Ae(o.evidenceOutcomes),this.replayEvidenceJournal(o),this.sessions.set(e,o),o)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let i=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),i}addEvidenceObligation(t,e,i=Date.now(),r){let o=this.registerSession(t),a=(r?void 0:o.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??_t(e.id,r,i);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:i,contract:e},`add\0${a}`),this.replayEvidenceJournal(o);let c=o.evidenceObligations.find(l=>l.obligationId===a);return c?(o.lastActivityAt=Date.now(),this.persist(o),structuredClone(c)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,i,r,o=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:o,fingerprint:c,violations:i.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=o,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let i=this.get(t);if(!i)return false;let r=i.evidenceObligations.find(s=>s.obligationId===e);if(!r)return false;let o=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:o},`resolve\0${e}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}degradeEvidenceObligation(t,e,i,r=Date.now()){let o=this.get(t),s=o?.evidenceObligations.find(c=>c.obligationId===e);if(!o||!s)return false;let a=i.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:r,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(o),o.lastActivityAt=r,this.persist(o),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,`${ke(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",ke(t))}appendEvidenceEvent(t,e,i){let r=this.evidenceJournalDir(t);mkdirSync(r,{recursive:true,mode:448});let o=createHash("sha256").update(i).digest("hex"),s=join$1(r,`${e.kind}-${o}.json`);if(existsSync(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Ee(t.evidenceObligations),t.evidenceDegradations=Se(t.evidenceDegradations),t.evidenceOutcomes=Ae(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let i;try{i=readdirSync(e).filter(o=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(o)).slice(0,4096);}catch{return}let r=i.flatMap(o=>{try{let s=readFileSync(join$1(e,o),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=It(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((o,s)=>o.at-s.at||De(o.kind)-De(s.kind));for(let o of r)this.applyEvidenceEvent(t,o);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let i=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(i)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let r=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!r||i||r.correctionFingerprint===e.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=e.at,r.correctionFingerprint=e.fingerprint,r.violations=e.violations;return}let o=r?.attempt??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!i&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:o}),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:o,...e.kind==="degrade"?{reason:e.reason}:{}}));}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),i=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(i,JSON.stringify(t),{mode:384}),renameSync(i,e);}};function Ee(n){return Array.isArray(n)?n.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!Te(e.contract))return [];let i=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Oe(e.contractId),r=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,o=e.correctionFingerprint??r;return o!==void 0&&!/^[a-f0-9]{64}$/.test(o)?[]:[{...e,obligationId:i,correctionFingerprint:o}]}).slice(-8):[]}function Se(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function Ae(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function It(n){if(!n||typeof n!="object")return null;let t=n,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let r={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Oe(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Te(t.contract)?{kind:e,...r,contract:t.contract}:null;if(e==="correction"){let o=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...r,fingerprint:o,violations:t.violations}:null}return e==="resolve"?{kind:e,...r}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...r,reason:t.reason}:null}function De(n){return n==="add"?0:n==="correction"?1:2}function Te(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,i=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(i)&&i.length<=16&&i.every(r=>typeof r=="string"&&r.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}var At=2,Dt=1;function Ct(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function $e(n=Ct()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let i=JSON.parse(readFileSync(e,"utf8"));if(i.version!==At&&i.version!==Dt||!Ot(i.commands)){console.error(`[devflow] command registry contract mismatch: ${e}`);continue}return i.commands}catch(i){console.error(`[devflow] command registry load failed: ${i.message}`);}return null}function Ot(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return Y(e.mcpTools)&&Y(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||Y(e.runtimePackages))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Y(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function Pe(n){let t=$e();return t?t[n]?.mcpTools??[]:[]}function je(n){let t=n.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function Fe(n,t){return t?`evt_tool_${createHash("sha256").update(`${n}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var Pt=256*1024,jt=48*1024;var Ft=5,j=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function Mt(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function Nt(n){let t=E(n,0,new Set);return t?Lt(t.contract,t.canonicalReport):null}function Me(n){if(!n.sessionId||!Mt(n.toolName))return null;let t=Nt(n.toolResponse);if(!t)return null;let e=Date.now(),i=n.runtimeStore.addEvidenceObligation(n.sessionId,t,e,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(i&&r){let o=openGlobalDevFlowDatabase();try{o.upsertSessionObligation({obligationId:`evidence:${i.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:t,runtimeObligationId:i.obligationId},createdAt:e,updatedAt:e});}finally{o.close();}}return qt(t)}function qt(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
|
|
2
|
+
`);}catch{}}function nt(n){return new Promise(t=>setTimeout(t,n))}function z(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function y(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(z(n))}function C(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let t=n,e={};for(let i of ["lastMcpCall","bypassCount"])if(i in t){let r=t[i];if(r==null)continue;e[i]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return e}function st(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function at(n){try{return existsSync(n)?C(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function ct(n,t){let e=t instanceof Error?t.message:String(t);console.error(`[devflow] Receipt ${n} skipped: ${e}`);}function pe(n){let t=y(n);for(let e of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync(join$1(t,e))&&unlinkSync(join$1(t,e));}catch{}}function lt(n,t){if(n.getHookReceipt(t)){pe(t);return}let e=join$1(y(t),"receipt.json");if(!existsSync(e))return;let i=at(e);n.updateHookReceipt(t,()=>i),pe(t);}function ge(n,t,e){let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),lt(i,n);let r={},o=i.updateHookReceipt(n,a=>(r=C(a),C(t(r)))),s=C(o);return {receipt:s,applied:!0,changed:!st(r,s)}}catch(r){return ct(e,r),{receipt:{},applied:false,changed:false}}finally{try{i?.close();}catch{}}}function J(n,t){return ge(n,()=>t,"write").applied}function B(n,t){return ge(n,t,"update")}var fe={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},dt=new Set(["Write","Edit","NotebookEdit"]),ut=new Set(["failed","timeout","unavailable"]);function pt(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var O=class{constructor(t,e,i){this.projectRoot=t;this.sessionId=e;this.executionId=i;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(e&&e.expiresAt>Date.now())return "context_ready";e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}return "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 i=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(i==="context_gathering"&&fe[t])return {permissionDecision:"deny",reasonCode:"DEVFLOW_CONTEXT_REQUIRED",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${t}.`};if(i==="context_ready"){if(dt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let r=fe[t];if(!r)return {permissionDecision:"allow"};let o=B(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!o.applied)return {permissionDecision:"allow"};let s=o.receipt.bypassCount??0,a=pt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){J(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,i,r){if(!this.sessionId||!this.executionId)return false;let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=o.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=r?.trim()?`${r.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return o.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||r&&d.toolUseId===r&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:r,reason:i?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?a:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{o?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let i=e.binding;if(i.requiredContextReceipt!==t.contextHash||i.projectRoot!==this.projectRoot||i.sessionId!==this.sessionId||i.requestId!==t.requestId||i.executionId&&i.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:"DevFlow canonical action binding is stale or mismatched. Call mcp__devflow__get_project_context again before writing."};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let r=(t.actionAttempts??[]).filter(o=>o.tool===e.tool&&ut.has(o.status));if(r.length>0){let o=r.at(-1),s={missedTool:e.tool,failedAttemptCount:r.length,reason:`${o.status}:${o.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool mcp__devflow__${e.tool} ${o.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 mcp__devflow__${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 i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let r=i.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!r||r.contextHash!==t.contextHash||r.actionDegradation)return;i.upsertContextReceipt({...r,actionDegradation:e});let o=i.getSkillExecution(t.executionId);if(!o)return;let s=o.metadata&&typeof o.metadata=="object"?o.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];i.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...o.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(o.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(o.fallbackCount??0)+1,fallbackReasons:[...new Set([...o.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{i?.close();}catch{}}}};var ve=1e4,ht=3e4,T=500,P=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","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,i,r,o=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:i,startedAt:r,projectRoot:o,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",i=Date.now(),r){let o={executionId:t,status:e,finishedAt:i,metadata:r},s=this.commitOrCache("execution_complete",o);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",o),s}async sendSessionStart(t,e,i){let r={id:t,projectRoot:e,startedAt:i,label:e.split("/").pop()??"unknown"},o=this.commitOrCache("session_start",r);return o&&this.postHttp("/api/telemetry/sessions",r),o}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 i={sessionId:t,finishedAt:e},r=this.commitOrCache("session_end",i);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),r}async flushCache(){try{let i=this.getDatabase(),r=i.listTelemetryFailures({unresolvedOnly:!0,limit:T}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),i.resolveTelemetryFailure(o.id);}catch{}i.trimTelemetryFailures(T);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(i=>!!i))].filter(i=>existsSync(i)).flatMap(i=>readdirSync(i).filter(r=>r.endsWith(".json")).map(r=>{let o=join$1(i,r);try{return {cacheFile:o,envelope:bt(JSON.parse(readFileSync(o,"utf8")),r)}}catch{return null}})).filter(i=>i!==null).sort((i,r)=>i.envelope.timestamp-r.envelope.timestamp||Re(i.envelope.operation)-Re(r.envelope.operation));for(let{cacheFile:i,envelope:r}of e)try{let o=this.getDatabase();o.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),o.resolveTelemetryFailure(r.id),unlinkSync(i);}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(i){return this.cacheOperation(t,e,i),false}}applyOperation(t,e){let i=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(i,e),i.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(i,e),i.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":i.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":i.ensureSession(e),i.insertRun({id:we(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(!i.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":i.closeSession(e.sessionId,e.finishedAt),i.updateRun(we(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let i=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!i)throw new Error("Canonical session ID is required for telemetry");let r=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:i,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,i){let r=Date.now(),o={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:i instanceof Error?i.message:String(i),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:o.id,operation:t,payload:e,error:o.failure,createdAt:r}),s.trimTelemetryFailures(T),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(o,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-T)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},ht).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){D(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ve?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ve)}...`}}};function Re(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function we(n){return `hook-run:${n}`}function bt(n,t){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let i=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!i)throw new Error("Unknown legacy telemetry cache operation");let r=e.payload??{},o=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:i,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:o}}function ke(n){return Buffer.from(n,"utf8").toString("base64url")}function _t(n,t,e){let i=t?.trim();if(i){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(i)?i:`tool-${createHash("sha256").update(i.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Oe(n){return `${n}:legacy-journal`}var k=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(y(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let i=this.get(e);if(i)return i.lastActivityAt=Date.now(),this.persist(i),i;let r=Date.now(),o={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(e,o),this.persist(o),o}startExecution(t,e,i){let r=this.registerSession(t);return (!r.executionId||r.skillName!==e)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=e,r.requiredMcpTools=[...new Set(i)],r.lastActivityAt=Date.now(),this.persist(r),r}get(t){let e=t.trim();if(!e)return null;let i=this.sessions.get(e);if(i)return this.replayEvidenceJournal(i),i;let r=this.snapshotPath(e);if(!existsSync(r))return null;try{let o=JSON.parse(readFileSync(r,"utf8"));return o.sessionId!==e||o.projectRoot!==this.projectRoot?null:(o.requiredMcpTools=Array.isArray(o.requiredMcpTools)?o.requiredMcpTools:[],o.evidenceObligations=Ee(o.evidenceObligations),o.evidenceDegradations=Se(o.evidenceDegradations),o.evidenceOutcomes=Ae(o.evidenceOutcomes),this.replayEvidenceJournal(o),this.sessions.set(e,o),o)}catch{return null}}completeExecution(t){let e=this.get(t);if(!e)return null;let i=structuredClone(e);return delete e.executionId,delete e.skillName,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),i}addEvidenceObligation(t,e,i=Date.now(),r){let o=this.registerSession(t),a=(r?void 0:o.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??_t(e.id,r,i);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:i,contract:e},`add\0${a}`),this.replayEvidenceJournal(o);let c=o.evidenceObligations.find(l=>l.obligationId===a);return c?(o.lastActivityAt=Date.now(),this.persist(o),structuredClone(c)):null}listEvidenceObligations(t){return (this.get(t)?.evidenceObligations??[]).map(e=>structuredClone(e))}markEvidenceCorrection(t,e,i,r,o=Date.now()){let s=this.get(t),a=s?.evidenceObligations.find(d=>d.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:o,fingerprint:c,violations:i.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=o,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let i=this.get(t);if(!i)return false;let r=i.evidenceObligations.find(s=>s.obligationId===e);if(!r)return false;let o=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:r.contractId,at:o},`resolve\0${e}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}degradeEvidenceObligation(t,e,i,r=Date.now()){let o=this.get(t),s=o?.evidenceObligations.find(c=>c.obligationId===e);if(!o||!s)return false;let a=i.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:r,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(o),o.lastActivityAt=r,this.persist(o),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,`${ke(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",ke(t))}appendEvidenceEvent(t,e,i){let r=this.evidenceJournalDir(t);mkdirSync(r,{recursive:true,mode:448});let o=createHash("sha256").update(i).digest("hex"),s=join$1(r,`${e.kind}-${o}.json`);if(existsSync(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Ee(t.evidenceObligations),t.evidenceDegradations=Se(t.evidenceDegradations),t.evidenceOutcomes=Ae(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync(e))return;let i;try{i=readdirSync(e).filter(o=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(o)).slice(0,4096);}catch{return}let r=i.flatMap(o=>{try{let s=readFileSync(join$1(e,o),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=It(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((o,s)=>o.at-s.at||De(o.kind)-De(s.kind));for(let o of r)this.applyEvidenceEvent(t,o);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let i=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(i)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let r=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!r||i||r.correctionFingerprint===e.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=e.at,r.correctionFingerprint=e.fingerprint,r.violations=e.violations;return}let o=r?.attempt??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!i&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:o}),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:o,...e.kind==="degrade"?{reason:e.reason}:{}}));}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),i=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(i,JSON.stringify(t),{mode:384}),renameSync(i,e);}};function Ee(n){return Array.isArray(n)?n.flatMap(t=>{if(!t||typeof t!="object")return [];let e=t;if(typeof e.contractId!="string"||e.contractId.length===0||e.contractId.length>128||typeof e.promptedAt!="number"||typeof e.attempt!="number"||typeof e.correctionRequested!="boolean"||!Array.isArray(e.violations)||!Te(e.contract))return [];let i=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Oe(e.contractId),r=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,o=e.correctionFingerprint??r;return o!==void 0&&!/^[a-f0-9]{64}$/.test(o)?[]:[{...e,obligationId:i,correctionFingerprint:o}]}).slice(-8):[]}function Se(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function Ae(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&(e.status==="resolved"||e.status==="degraded")&&typeof e.completedAt=="number"&&typeof e.attempt=="number"&&(e.reason===void 0||typeof e.reason=="string")}).slice(-20):[]}function It(n){if(!n||typeof n!="object")return null;let t=n,e=t.kind;if(e!=="add"&&e!=="correction"&&e!=="resolve"&&e!=="degrade"||typeof t.contractId!="string"||t.contractId.length>128||typeof t.at!="number")return null;let r={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Oe(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Te(t.contract)?{kind:e,...r,contract:t.contract}:null;if(e==="correction"){let o=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...r,fingerprint:o,violations:t.violations}:null}return e==="resolve"?{kind:e,...r}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...r,reason:t.reason}:null}function De(n){return n==="add"?0:n==="correction"?1:2}function Te(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,i=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(i)&&i.length<=16&&i.every(r=>typeof r=="string"&&r.length<=128)&&typeof t.canonicalReport=="string"&&Buffer.byteLength(t.canonicalReport,"utf8")<=48*1024&&!!t.correctionPolicy&&t.correctionPolicy.maxAttempts===1&&t.correctionPolicy.repeatedViolation==="fail_open"}var At=2,Dt=1;function Ct(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function Pe(n=Ct()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync(e))continue;let i=JSON.parse(readFileSync(e,"utf8"));if(i.version!==At&&i.version!==Dt||!Ot(i.commands)){console.error(`[devflow] command registry contract mismatch: ${e}`);continue}return i.commands}catch(i){console.error(`[devflow] command registry load failed: ${i.message}`);}return null}function Ot(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(t=>{if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return Y(e.mcpTools)&&Y(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||Y(e.runtimePackages))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Y(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function $e(n){let t=Pe();return t?t[n]?.mcpTools??[]:[]}function je(n){let t=n.trim().replace(/^\//,"");if(!t.startsWith("devflow:"))return null;let e=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(e)?`devflow:${e.toLowerCase()}`:null}function Fe(n,t){return t?`evt_tool_${createHash("sha256").update(`${n}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var $t=256*1024,jt=48*1024;var Ft=5,j=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function Mt(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function Nt(n){let t=E(n,0,new Set);return t?Lt(t.contract,t.canonicalReport):null}function Me(n){if(!n.sessionId||!Mt(n.toolName))return null;let t=Nt(n.toolResponse);if(!t)return null;let e=Date.now(),i=n.runtimeStore.addEvidenceObligation(n.sessionId,t,e,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(i&&r){let o=openGlobalDevFlowDatabase();try{o.upsertSessionObligation({obligationId:`evidence:${i.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:t,runtimeObligationId:i.obligationId},createdAt:e,updatedAt:e});}finally{o.close();}}return qt(t)}function qt(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
|
|
3
3
|
|
|
4
|
-
`)}function E(n,t,e){if(t>Ft||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")
|
|
5
|
-
`)||null}finally{e.close();}}function Qt(n){let t=rn(n.projectRoot),e=on(n.projectRoot),i=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},o=null;if(n.kind==="formatter"&&(r.prettier||sn(n.projectRoot)))o=F(e,"prettier",[n.mode==="write"?"--write":"--check",n.targetFile],6e4);else if(n.kind==="typecheck"){let s=ee(i,["typecheck","type-check","check:types"]);s?o=Q(e,s,12e4):r.typescript&&existsSync$1(join(n.projectRoot,"tsconfig.json"))&&(o=F(e,"tsc",["--noEmit","--pretty","false"],12e4));}else if(n.kind==="lint"){let s=ee(i,["lint"]);s&&(o=Q(e,s,12e4));}else if(n.kind==="test"){let s=an(n.projectRoot,n.targetFile);s&&r.vitest?o=F(e,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(o=F(e,"jest",["--runTestsByPath",s],12e4));}else if(n.kind==="build"){let s=ee(i,["build"]);s&&(o=Q(e,s,18e4));}else n.kind==="generated_files"&&(o={command:"git",args:["diff","--check","--",n.targetFile],timeoutMs:3e4});return o?{kind:n.kind,...o,display:[o.command,...o.args].map(cn).join(" "),required:n.required,targetFile:n.targetFile,contextReceipt:n.contextReceipt}:null}function Q(n,t,e){return n==="yarn"?{command:"yarn",args:["run",t],timeoutMs:e}:n==="pnpm"?{command:"pnpm",args:["run",t],timeoutMs:e}:n==="bun"?{command:"bun",args:["run",t],timeoutMs:e}:{command:"npm",args:["run",t],timeoutMs:e}}function F(n,t,e,i){return n==="pnpm"?{command:"pnpm",args:["exec",t,...e],timeoutMs:i}:n==="yarn"?{command:"yarn",args:[t,...e],timeoutMs:i}:n==="bun"?{command:"bunx",args:[t,...e],timeoutMs:i}:{command:"npx",args:["--no-install",t,...e],timeoutMs:i}}function en(n,t){let e=t.file_path??t.notebook_path;if(typeof e!="string"||!e.trim())return null;let i=isAbsolute(e)?resolve(e):resolve(n,e);return tn(n,i)?relative(n,i).split(sep).join("/"):null}function tn(n,t){let e=isAbsolute(t)?resolve(t):resolve(n,t),i=relative(resolve(n),e);return i!==""&&i!==".."&&!i.startsWith(`..${sep}`)&&!isAbsolute(i)}function nn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.ok===false||t.success===false||t.isError===true||!!t.error}function rn(n){try{return JSON.parse(readFileSync$1(join(n,"package.json"),"utf8"))}catch{return null}}function on(n){return existsSync$1(join(n,"pnpm-lock.yaml"))?"pnpm":existsSync$1(join(n,"yarn.lock"))?"yarn":existsSync$1(join(n,"bun.lockb"))||existsSync$1(join(n,"bun.lock"))?"bun":"npm"}function sn(n){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync$1(join(n,t)))}function ee(n,t){return t.find(e=>typeof n[e]=="string"&&n[e].trim())??null}function an(n,t){let e=t.replace(/\.[^.]+$/u,""),i=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of i){let a=`${e}${s}`;if(existsSync$1(join(n,a)))return a}let r=join(n,t.split("/").slice(0,-1).join("/")),o=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!o||!existsSync$1(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${o}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(n,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function cn(n){return /^[A-Za-z0-9_./:@=-]+$/u.test(n)?n:JSON.stringify(n)}var yn=new Set(["Agent","Bash","Glob","Grep","WebSearch","WebFetch"]);function He(n){if(!n)return;let t=typeof n.status=="string"?n.status:void 0;if(!(n.ok===false||n.success===false||n.isError===true||t==="failed"||t==="rejected"||!!n.error))return;let i=n.error;if(typeof i=="string"&&i.trim())return i;if(i&&typeof i=="object"){let r=i;if(typeof r.message=="string"&&r.message.trim())return r.message;if(typeof r.code=="string"&&r.code.trim())return r.code}return t?`Tool response status: ${t}`:"Tool response reported failure"}function hn(n,t,e,i){try{let r=join$1(y(n),"event-map.json");if(!existsSync(r))return null;let o=JSON.parse(readFileSync(r,"utf-8")),s=o.filter(l=>l.toolName===e&&(!l.sessionId||l.sessionId===t));if(s.length===0)return null;let a=i?s.find(l=>l.toolUseId===i):s.sort((l,d)=>l.timestamp-d.timestamp)[0];if(!a)return null;let c=o.findIndex(l=>l.eventId===a.eventId);return c!==-1&&o.splice(c,1),writeFileSync(r,JSON.stringify(o)),{eventId:a.eventId,timestamp:a.timestamp}}catch{return null}}function Ue(n){if(!n)return 0;let t=n;if(typeof n=="string")try{t=JSON.parse(n);}catch{return 1}let e=t,i=["files","results","data","result","memories","nodes","chunks","findings","symbols","keySymbols"],r=["reasoning","riskHints","nextActions"],o=Array.isArray(e.data)?e.data:e.structuredContent??e;if(Array.isArray(o))return o.length;if(typeof o=="object"&&o!==null){let s=o,a=0,c=false;for(let d of i)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let d of r)Array.isArray(s[d])&&(a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=Ue(d));let l=!!(s._devflow||s._devflow_unique||s.taskType);return a===0&&l&&!c?1:a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}function bn(n,t){if(!yn.has(t))return null;let e=B(n,r=>({...r,bypassCount:(r.bypassCount??0)+1}));if(!e.applied)return null;let i=e.receipt.bypassCount??0;return i>20&&i%10===0?`MCP \u5DE5\u5177\u4F7F\u7528\u7387\u4F4E\uFF1A${i} \u6B21\u76F4\u63A5\u5DE5\u5177\u8C03\u7528\u3002\u5EFA\u8BAE\u4F7F\u7528 get_project_context \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`:null}async function vn(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",i=z(),r=t.tool_input||{},o=t.tool_response||{},s=t.session_id?.trim()||null,a=new k(i);if(s&&a.registerSession(s),e==="Skill"){let f=typeof r=="object"&&r.skill?r.skill:"",g=je(f);s&&g&&(a.startExecution(s,g
|
|
4
|
+
`)}function E(n,t,e){if(t>Ft||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>$t)return null;try{return E(JSON.parse(n),t+1,e)}catch{return null}}if(typeof n!="object"||e.has(n))return null;if(e.add(n),Array.isArray(n)){for(let r of n.slice(0,16)){let o=E(r,t+1,e);if(o)return o}return null}let i=n;if("evidenceContract"in i)return {contract:i.evidenceContract,canonicalReport:i.canonicalReport};for(let r of ["structuredContent","data","result"])if(r in i){let o=E(i[r],t+1,e);if(o)return o}if(Array.isArray(i.content))for(let r of i.content.slice(0,16)){let o=r&&typeof r=="object"&&"text"in r?r.text:r,s=E(o,t+1,e);if(s)return s}return null}function Lt(n,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let e=n;if(e.version!=="1.0"||typeof e.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)||typeof e.runtimeProfilingOccurred!="boolean"||typeof e.samplingEvidenceOccurred!="boolean"||!Array.isArray(e.requiredSections)||e.requiredSections.length!==j.length)return null;let i=e.requiredSections.filter(c=>typeof c=="string");if(i.length!==j.length||j.some((c,l)=>i[l]!==c)||!Array.isArray(e.prohibitedClaims)||e.prohibitedClaims.length>16)return null;let r=e.prohibitedClaims.filter(c=>typeof c=="string"&&c.length<=128);if(r.length!==e.prohibitedClaims.length)return null;let o=e.correctionPolicy;if(!o||typeof o!="object"||Array.isArray(o))return null;let s=o;if(s.maxAttempts!==1||s.repeatedViolation!=="fail_open")return null;let a=typeof e.canonicalReport=="string"?e.canonicalReport:t;return typeof a!="string"||Buffer.byteLength(a,"utf8")>jt||j.some(c=>!a.includes(c))?null:{version:"1.0",id:e.id,runtimeProfilingOccurred:e.runtimeProfilingOccurred,samplingEvidenceOccurred:e.samplingEvidenceOccurred,requiredSections:i,prohibitedClaims:r,correctionPolicy:{maxAttempts:1,repeatedViolation:"fail_open"},canonicalReport:a}}function qe(n){let t;try{if(Jt(n.toolResponse))return null;t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let e=t.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);if(!e)return null;let i=n.toolName==="Read"?zt(n.toolInput):void 0,r=i?e.selectedFiles?.find(d=>Vt(n.projectRoot,d,i)):void 0,o=Wt(n.toolName),s=r?"code":e.canonicalNextAction===o?"action":null,a=r??(s==="action"?o:void 0);if(!s||!a)return null;let c=[e.contextHash,e.requestId??"",s,a,n.toolUseId??`${n.sessionId}:${n.executionId??e.executionId}`].join("\0");t.recordContextSelectionEvent({id:`ctxsel:${createHash$1("sha256").update(c).digest("hex").slice(0,32)}`,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:e.executionId,requestId:e.requestId,selectionType:s,candidateId:a,toolName:n.toolName,toolUseId:n.toolUseId,selectedAt:Date.now()});let l=t.listRetrievalLedgerEvents({projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:e.executionId,requestId:e.requestId}).find(d=>d.sourceType===s&&d.sourceId===a&&d.stage==="selected");return l&&t.appendRetrievalLedgerEvent({...l,id:Bt(l.id,"adopted",n.toolUseId??n.toolName),stage:"adopted",toolEvidence:[n.toolUseId??n.toolName],payload:{...l.payload,adoptedByTool:n.toolName},createdAt:Date.now()}),s}catch{return null}finally{try{t?.close();}catch{}}}function zt(n){for(let t of ["file_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}}function Vt(n,t,e){let i=resolve(n,t),r=isAbsolute(e)?resolve(e):resolve(n,e);return i===r}function Wt(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}function Jt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.ok===false||t.success===false||t.isError===true||!!t.error||["failed","rejected","unavailable"].includes(String(t.status??""))}function Bt(n,t,e){return `retrieval:${createHash$1("sha256").update(`${n}\0${t}\0${e}`).digest("hex")}`}var Xt=new Set(["Write","Edit","NotebookEdit"]);function Le(n){if(!Xt.has(n.toolName)||nn(n.toolResponse))return null;let t=en(n.projectRoot,n.toolInput);if(!t)return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let i=e.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId),r=i?.canonicalAction?.verificationPlan??[];if(!i||r.length===0)return null;let o=[],s=[];for(let c of r){let l=Qt({projectRoot:n.projectRoot,targetFile:t,kind:c.kind,mode:c.mode==="write"?"write":"check",required:c.required===!0,contextReceipt:i.contextHash}),d=`${i.contextHash}\0${n.toolUseId??t}\0${c.kind}\0${t}`,u=`policy-verification:${createHash$1("sha256").update(d).digest("hex")}`,p=Date.now();if(!l){let I=`verification_unavailable:${c.kind}`;e.upsertSessionObligation({obligationId:u,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,kind:"evidence_contract",state:"degraded",payload:{subtype:"policy_verification",status:"unknown",verificationKind:c.kind,targetFile:t,contextReceipt:i.contextHash},reason:I,createdAt:p,updatedAt:p,resolvedAt:p}),s.push(c.kind);continue}let M={...l,obligationId:u,sessionId:n.sessionId,executionId:n.executionId,requestId:i.requestId};e.upsertSessionObligation({obligationId:u,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,kind:"evidence_contract",state:"open",payload:{subtype:"policy_verification",status:"scheduled",verificationKind:c.kind,command:l.display,targetFile:t,contextReceipt:i.contextHash,required:c.required===!0},createdAt:p,updatedAt:p}),e.enqueueWork({idempotencyKey:u,kind:"verification.policy",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:M,maxAttempts:2,nextAttemptAt:p}),o.push(l.display);}return [o.length>0?`DevFlow scheduled policy verification: ${o.join(" && ")}`:"",s.length>0?`Verification unavailable and recorded as unknown: ${s.join(", ")}`:""].filter(Boolean).join(`
|
|
5
|
+
`)||null}finally{e.close();}}function Qt(n){let t=rn(n.projectRoot),e=on(n.projectRoot),i=t?.scripts??{},r={...t?.dependencies,...t?.devDependencies},o=null;if(n.kind==="formatter"&&(r.prettier||sn(n.projectRoot)))o=F(e,"prettier",[n.mode==="write"?"--write":"--check",n.targetFile],6e4);else if(n.kind==="typecheck"){let s=ee(i,["typecheck","type-check","check:types"]);s?o=Q(e,s,12e4):r.typescript&&existsSync$1(join(n.projectRoot,"tsconfig.json"))&&(o=F(e,"tsc",["--noEmit","--pretty","false"],12e4));}else if(n.kind==="lint"){let s=ee(i,["lint"]);s&&(o=Q(e,s,12e4));}else if(n.kind==="test"){let s=an(n.projectRoot,n.targetFile);s&&r.vitest?o=F(e,"vitest",["run",s],12e4):s&&(r.jest||r["@jest/core"])&&(o=F(e,"jest",["--runTestsByPath",s],12e4));}else if(n.kind==="build"){let s=ee(i,["build"]);s&&(o=Q(e,s,18e4));}else n.kind==="generated_files"&&(o={command:"git",args:["diff","--check","--",n.targetFile],timeoutMs:3e4});return o?{kind:n.kind,...o,display:[o.command,...o.args].map(cn).join(" "),required:n.required,targetFile:n.targetFile,contextReceipt:n.contextReceipt}:null}function Q(n,t,e){return n==="yarn"?{command:"yarn",args:["run",t],timeoutMs:e}:n==="pnpm"?{command:"pnpm",args:["run",t],timeoutMs:e}:n==="bun"?{command:"bun",args:["run",t],timeoutMs:e}:{command:"npm",args:["run",t],timeoutMs:e}}function F(n,t,e,i){return n==="pnpm"?{command:"pnpm",args:["exec",t,...e],timeoutMs:i}:n==="yarn"?{command:"yarn",args:[t,...e],timeoutMs:i}:n==="bun"?{command:"bunx",args:[t,...e],timeoutMs:i}:{command:"npx",args:["--no-install",t,...e],timeoutMs:i}}function en(n,t){let e=t.file_path??t.notebook_path;if(typeof e!="string"||!e.trim())return null;let i=isAbsolute(e)?resolve(e):resolve(n,e);return tn(n,i)?relative(n,i).split(sep).join("/"):null}function tn(n,t){let e=isAbsolute(t)?resolve(t):resolve(n,t),i=relative(resolve(n),e);return i!==""&&i!==".."&&!i.startsWith(`..${sep}`)&&!isAbsolute(i)}function nn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let t=n;return t.ok===false||t.success===false||t.isError===true||!!t.error}function rn(n){try{return JSON.parse(readFileSync$1(join(n,"package.json"),"utf8"))}catch{return null}}function on(n){return existsSync$1(join(n,"pnpm-lock.yaml"))?"pnpm":existsSync$1(join(n,"yarn.lock"))?"yarn":existsSync$1(join(n,"bun.lockb"))||existsSync$1(join(n,"bun.lock"))?"bun":"npm"}function sn(n){return [".prettierrc",".prettierrc.json",".prettierrc.js",".prettierrc.cjs","prettier.config.js","prettier.config.cjs"].some(t=>existsSync$1(join(n,t)))}function ee(n,t){return t.find(e=>typeof n[e]=="string"&&n[e].trim())??null}function an(n,t){let e=t.replace(/\.[^.]+$/u,""),i=[".test.ts",".test.tsx",".spec.ts",".spec.tsx",".test.js",".spec.js"];for(let s of i){let a=`${e}${s}`;if(existsSync$1(join(n,a)))return a}let r=join(n,t.split("/").slice(0,-1).join("/")),o=t.split("/").at(-1)?.replace(/\.[^.]+$/u,"");if(!o||!existsSync$1(r))return null;try{return readdirSync$1(r).filter(s=>s.startsWith(`${o}.`)&&/\.(?:test|spec)\.[cm]?[jt]sx?$/u.test(s)).map(s=>relative(n,join(r,s)).split(sep).join("/"))[0]??null}catch{return null}}function cn(n){return /^[A-Za-z0-9_./:@=-]+$/u.test(n)?n:JSON.stringify(n)}var yn=new Set(["Agent","Bash","Glob","Grep","WebSearch","WebFetch"]);function He(n){if(!n)return;let t=typeof n.status=="string"?n.status:void 0;if(!(n.ok===false||n.success===false||n.isError===true||t==="failed"||t==="rejected"||!!n.error))return;let i=n.error;if(typeof i=="string"&&i.trim())return i;if(i&&typeof i=="object"){let r=i;if(typeof r.message=="string"&&r.message.trim())return r.message;if(typeof r.code=="string"&&r.code.trim())return r.code}return t?`Tool response status: ${t}`:"Tool response reported failure"}function hn(n,t,e,i){try{let r=join$1(y(n),"event-map.json");if(!existsSync(r))return null;let o=JSON.parse(readFileSync(r,"utf-8")),s=o.filter(l=>l.toolName===e&&(!l.sessionId||l.sessionId===t));if(s.length===0)return null;let a=i?s.find(l=>l.toolUseId===i):s.sort((l,d)=>l.timestamp-d.timestamp)[0];if(!a)return null;let c=o.findIndex(l=>l.eventId===a.eventId);return c!==-1&&o.splice(c,1),writeFileSync(r,JSON.stringify(o)),{eventId:a.eventId,timestamp:a.timestamp}}catch{return null}}function Ue(n){if(!n)return 0;let t=n;if(typeof n=="string")try{t=JSON.parse(n);}catch{return 1}let e=t,i=["files","results","data","result","memories","nodes","chunks","findings","symbols","keySymbols"],r=["reasoning","riskHints","nextActions"],o=Array.isArray(e.data)?e.data:e.structuredContent??e;if(Array.isArray(o))return o.length;if(typeof o=="object"&&o!==null){let s=o,a=0,c=false;for(let d of i)Array.isArray(s[d])&&(c=true,a+=s[d].length);for(let d of r)Array.isArray(s[d])&&(a+=s[d].length);for(let[,d]of Object.entries(s))d&&typeof d=="object"&&!Array.isArray(d)&&(a+=Ue(d));let l=!!(s._devflow||s._devflow_unique||s.taskType);return a===0&&l&&!c?1:a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}function bn(n,t){if(!yn.has(t))return null;let e=B(n,r=>({...r,bypassCount:(r.bypassCount??0)+1}));if(!e.applied)return null;let i=e.receipt.bypassCount??0;return i>20&&i%10===0?`MCP \u5DE5\u5177\u4F7F\u7528\u7387\u4F4E\uFF1A${i} \u6B21\u76F4\u63A5\u5DE5\u5177\u8C03\u7528\u3002\u5EFA\u8BAE\u4F7F\u7528 get_project_context \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`:null}async function vn(n){if(!n)return null;let t;try{t=JSON.parse(n);}catch{return null}let e=t.tool_name||"",i=z(),r=t.tool_input||{},o=t.tool_response||{},s=t.session_id?.trim()||null,a=new k(i);if(s&&a.registerSession(s),e==="Skill"){let f=typeof r=="object"&&r.skill?r.skill:"",g=je(f);s&&g&&(a.startExecution(s,g,$e(g)),J(i,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}let c=s?a.get(s):null;if(e.startsWith("mcp__")){let f=new O(i,s??void 0,c?.executionId??s??void 0);f.recordMcpCall();let g=He(typeof o=="object"&&o!==null?o:null),R=e.replace(/^mcp__[^_]+__/,"");f.recordDomainActionOutcome(R,g?Rn(g):"succeeded",g,t.tool_use_id);}s&&qe({projectRoot:i,sessionId:s,executionId:c?.executionId,toolName:e,toolInput:r,toolResponse:o,toolUseId:t.tool_use_id});let l=s?hn(i,s,e,t.tool_use_id):null,d=s&&t.tool_use_id&&!l?(()=>{try{let f=openGlobalDevFlowDatabase();try{return f.getToolCallEventByToolUseId(s,t.tool_use_id)}finally{f.close();}}catch{return null}})():null,u=l??d,p=typeof o=="object"&&o!==null?o:null,M=JSON.stringify(o),I=Buffer.byteLength(M,"utf8"),re=Ue(o);if(c?.executionId!==void 0||e.startsWith("mcp__devflow__")||e==="Skill"){let f=getLogWriter(i),g=c?.executionId??`auto-${s??Date.now()}`;f.toolCall({tool:e,runId:g,stepId:`step-${g}`,input:r,output:o,duration:u?Math.max(0,Date.now()-u.timestamp):0,success:!p?.error,resultCount:re,resultSizeBytes:I,error:p?.error});}if(u&&s){let f=typeof o=="string"?o:JSON.stringify(o),g=f.length>5e3?{_truncated:true,_originalSize:f.length,text:f.slice(0,5e3)}:o,R=He(p),Je=R?classifyWorkflowFailure({stepId:e,toolName:e,output:o,error:new Error(R),errorStack:R}).category:void 0;await new P().completeEvent({eventId:u.eventId,sessionId:s,output:g,error:R,failureCategory:Je,duration:u?Math.max(0,Date.now()-u.timestamp):0,completedAt:Date.now()});}let N=typeof r=="object"&&r.command?r.command:"",A=p?.exitCode,oe=p?.stderr,ze=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,b,v,q=true;if(e.startsWith("mcp__"))b="mcp_call",v={mcpTool:e.replace(/^mcp__[^_]+__/,""),query:typeof r=="object"&&r.query?r.query:null,resultCount:re,resultSizeBytes:I};else if(e==="Read"||e==="Write"||e==="Edit")b=e==="Read"?"file_read":"file_write",v={filePath:typeof r=="object"&&r.file_path?r.file_path:null,fileContentSize:I};else if(e==="Bash"){let f=ze.test(N),g=A!==void 0&&A!==0;q=!f||g,b=g?"bash_error":"bash_command",v={command:N||e,exitCode:A??null,stderr:oe??null};}else e==="Agent"?(b="subagent",v={subagentType:typeof r=="object"&&r.subagent_type?r.subagent_type:null,description:typeof r=="object"&&r.description?String(r.description).slice(0,200):null}):e==="WebSearch"||e==="WebFetch"?(b=e==="WebSearch"?"web_search":"web_fetch",v={query:typeof r=="object"&&r.query?String(r.query).slice(0,200):null}):(q=false,b="tool_use",v={});if(q){let f={id:t.tool_use_id?`memory:${Fe(s??"",t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s??"",tool:e,kind:b,payload:v,command:N||void 0,exitCode:A,stderr:oe??void 0,durationMs:u?Math.max(0,Date.now()-u.timestamp):0,createdAt:Date.now()};s&&D(`/api/memory/session-events?rootPath=${encodeURIComponent(i)}`,f);}let Ve=Me({toolName:e,toolResponse:o,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:a}),We=s?Le({projectRoot:i,sessionId:s,executionId:c?.executionId,toolName:e,toolInput:r,toolResponse:o,toolUseId:t.tool_use_id}):null,L=bn(i,e);return L&&console.error("[devflow] Enforcement:",L),[Ve,We,L].filter(f=>!!f).join(`
|
|
6
6
|
|
|
7
7
|
`)||null}function Rn(n){return /timeout|timed out|deadline|warming/i.test(n)?"timeout":/unavailable|not active|unknown tool|not found|not registered|route not found/i.test(n)?"unavailable":"failed"}if(process.argv[1]?.endsWith("post-tool-use")||process.argv[1]?.endsWith("post-tool-use.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",e=>{t+=e;}),process.stdin.on("end",async()=>{let e=await vn(t.trim()||process.argv[2]||"");n(JSON.stringify(e?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:e}}:{status:"ok"}));}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref();}export{vn as handlePostToolUse};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {getLocalApiKey,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {MemoryGate}from'@devflow-tools/memory-engine';import {existsSync as existsSync$1,readFileSync,rmSync as rmSync$1,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync as unlinkSync$1}from'fs';import {join as join$1}from'path';import {homedir as homedir$1}from'os';import {request}from'node:http';import {mkdirSync,existsSync,writeFileSync,renameSync,unlinkSync,rmSync,lstatSync,openSync,constants,fstatSync,readSync,closeSync,appendFileSync}from'node:fs';import {join}from'node:path';import {homedir}from'node:os';import {createHash}from'node:crypto';import {randomUUID,createHash as createHash$1}from'crypto';function B(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(i){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(B(i))}function Q(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
|
|
2
|
-
`);}catch{}}function Xe(i){return new Promise(t=>setTimeout(t,i))}var ye=1e4,tt=3e4,W=500,G=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","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 a={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}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 n=this.getDatabase(),o=n.listTelemetryFailures({unresolvedOnly:!0,limit:W}).reverse();for(let r of o)try{this.applyOperation(r.operation,r.payload),n.resolveTelemetryFailure(r.id);}catch{}n.trimTelemetryFailures(W);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(n=>!!n))].filter(n=>existsSync$1(n)).flatMap(n=>readdirSync(n).filter(o=>o.endsWith(".json")).map(o=>{let r=join$1(n,o);try{return {cacheFile:r,envelope:nt(JSON.parse(readFileSync(r,"utf8")),o)}}catch{return null}})).filter(n=>n!==null).sort((n,o)=>n.envelope.timestamp-o.envelope.timestamp||he(n.envelope.operation)-he(o.envelope.operation));for(let{cacheFile:n,envelope:o}of e)try{let r=this.getDatabase();r.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),r.resolveTelemetryFailure(o.id),unlinkSync$1(n);}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:be(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(be(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(W),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(s,JSON.stringify(r,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-W)))unlinkSync$1(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},tt).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){j(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ye?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ye)}...`}}};function he(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function be(i){return `hook-run:${i}`}function nt(i,t){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let e=i;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let n=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!n)throw new Error("Unknown legacy telemetry cache operation");let o=e.payload??{},r=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:n,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:r}}async function ve(i){let t=!i.memory,e=i.memory??new MemoryGate(i.projectRoot),n=0,o=0;try{await e.forceWarmUp(),i.trigger==="session_end"&&(n=await e.releasePendingDistillLeases(i.sessionId)),o=e.getPendingEventCount(i.sessionId,i.trigger!=="session_end");}finally{t&&e.close();}let r=Date.now(),s=i.trigger==="session_end"&&i.sessionId?`distill:session_end:${createHash("sha256").update(`${i.projectRoot}\0${i.sessionId}`).digest("hex").slice(0,24)}`:`distill:${r}:${Math.random().toString(36).slice(2,10)}`,a={id:s,pendingEvents:o,releasedLeases:n,trigger:i.trigger,sessionId:i.sessionId,details:i.details};try{let c=openGlobalDevFlowDatabase();try{c.recordMemoryDistillCheckpoint({id:s,projectRoot:i.projectRoot,sessionId:i.sessionId,trigger:i.trigger,pendingEvents:o,releasedLeases:n,details:i.details,createdAt:r}),c.insertEvent({kind:"memory_distill_requested",timestamp:r,success:!0,metadata:{...a,projectRoot:i.projectRoot}});}finally{c.close();}}catch(c){throw c}return a}function _e(i){return Buffer.from(i,"utf8").toString("base64url")}function lt(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash$1("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function De(i){return `${i}:legacy-journal`}var L=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(k(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let 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)],o.lastActivityAt=Date.now(),this.persist(o),o}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$1(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=ke(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,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),a=(o?void 0:r.evidenceObligations.find(u=>u.contractId===e.id))?.obligationId??lt(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:n,contract:e},`add\0${a}`),this.replayEvidenceJournal(r);let c=r.evidenceObligations.find(u=>u.obligationId===a);return c?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(c)):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),a=s?.evidenceObligations.find(p=>p.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(o)?o:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:r,fingerprint:c,violations:n.slice(0,16).map(p=>p.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let u=s.evidenceObligations.find(p=>p.obligationId===e);return u?structuredClone(u):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}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(c=>c.obligationId===e);if(!r||!s)return false;let a=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync$1(this.snapshotPath(e),{force:true}),rmSync$1(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$1(o,{recursive:true,mode:448});let r=createHash$1("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync$1(s))return;let a=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync$1(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Re(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=ke(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(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 a=dt(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||Ae(r.kind)-Ae(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(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let 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??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!n&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r}),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$1(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(n,JSON.stringify(t),{mode:384}),renameSync$1(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)||!Oe(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:De(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 ke(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 dt(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:De(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Oe(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 Ae(i){return i==="add"?0:i==="correction"?1:2}function Oe(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 $e(i,t){let e=ft(i);mkdirSync(e,{recursive:true,mode:448});let n=join(e,`${t.receiptId}.json`);if(existsSync(n))return t.receiptId;let o=`${n}.${process.pid}.tmp`;writeFileSync(o,JSON.stringify(t),{mode:384});try{renameSync(o,n);}catch(r){try{unlinkSync(o);}catch{}if(!existsSync(n))throw r}return t.receiptId}function ft(i){return join(k(i),"session-finalize-pending")}var wt=512*1024,It=500;var _t=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function Rt(i){let t=false,e=[],n=[];for(let o of i){if(/^\s*```/.test(o)){t=!t,e.push(""),n.push(o.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}e.push(t?"":o.replace(/`[^`]*`/g,"").trim()),n.push(o.replace(/`([^`]*)`/g,(r,s)=>Et(s)?"":s).trim());}return {headingLines:e,claimLines:n}}function Et(i){let t=i.trim().slice(0,256);return !t||/\s/.test(t)||i.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(t)||/^(['"])[^'"`]*\1$/.test(t)}function kt(i,t){if(!i||i.length>4096)return {degradationReason:"transcript_path_missing"};let e;try{let n=lstatSync(i);if(!n.isFile()||n.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};e=openSync(i,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let o=fstatSync(e);if(!o.isFile()||o.dev!==n.dev||o.ino!==n.ino)return {degradationReason:"transcript_path_changed"};let r=Math.min(o.size,wt),s=Buffer.alloc(r),a=0;for(;a<r;){let h=readSync(e,s,a,r-a,o.size-r+a);if(h===0)break;a+=h;}let c=s.subarray(0,a).toString("utf8");o.size>r&&(c=c.slice(Math.max(0,c.indexOf(`
|
|
3
|
-
`)+1)));let u=c.split(/\r?\n/).slice(-
|
|
4
|
-
`):"";if(p.trim()){let g=p.trim(),y=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof r.uuid=="string"&&r.uuid?`uuid:${r.uuid}`:`record:${String(r.timestamp??"")}:${n}:${createHash("sha256").update(o).digest("hex")}`,b=createHash("sha256").update(g).digest("hex"),h=createHash("sha256").update(`${y}\0${b}`).digest("hex");e.push({text:g,timestamp:c,fingerprint:h});}}catch{continue}}return e}function Dt(i){if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i!="string")return 0;let t=Date.parse(i);return Number.isFinite(t)?t:0}function Ot(i){let t=new Set,e=new Map,n;for(let o=0;o<i.length;o++){let r=i[o].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=_t.find(a=>r===a);s&&(n=s,t.add(s)),e.set(o,n);}return {found:t,byLine:e}}function Me(i){let t=openGlobalDevFlowDatabase();try{let e=t.listRetrievalLedgerEvents(i),n=new Map(e.filter(c=>c.stage==="selected").map(c=>[`${c.sourceType}\0${c.sourceId}`,c])),o=new Map(e.filter(c=>c.stage==="adopted").map(c=>[`${c.sourceType}\0${c.sourceId}`,c])),r=0,s=0,a=0;for(let[c,u]of n){let p=o.get(c),g=p&&i.verificationReceipt&&i.outcome!=="unknown"?i.outcome:"unknown",y=g==="positive"?"positive_outcome":g==="negative"?"negative_outcome":"unknown";t.appendRetrievalLedgerEvent({...u,id:$t(u.id,y,i.verificationReceipt??i.sessionId),stage:y,reason:p?i.outcomeReason:"selected_not_adopted",toolEvidence:p?.toolEvidence??[],verificationReceipt:g==="unknown"?void 0:i.verificationReceipt,payload:{...u.payload,adopted:!!p},createdAt:i.finishedAt??Date.now()}),y==="positive_outcome"?r+=1:y==="negative_outcome"?s+=1:a+=1;}return {adopted:o.size,positive:r,negative:s,unknown:a}}finally{t.close();}}function $t(i,t,e){return `retrieval:${createHash("sha256").update(`${i}\0${t}\0${e}`).digest("hex")}`}function zt(i){let t={committed:0,skipped:0,pending:0},e=[];for(let n of i)t[n.status]+=1,n.receiptId&&e.push(n.receiptId);return {memoryReceiptIds:[...new Set(e)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function D(i){return (i instanceof Error?i.message:String(i)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var I=class extends Error{constructor(t,e){super(`session_finalize_${t}:${e}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function N(i){let t;try{t=openGlobalDevFlowDatabase();let e=(i.executionId?t.getSkillExecution(i.executionId):null)??t.getLatestSkillExecutionForSession(i.sessionId),n={stage:i.stage,reason:i.reason,degradedAt:Date.now()};e&&t.mergeSkillExecutionMetadata(e.executionId,{...i.metadata,sessionFinalizationDegradations:[n]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:n.degradedAt,success:!1,metadata:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:e?.executionId,...n}});}catch{}finally{t?.close();}}function jt(i,t=B(),e=true,n,o=true){let r;try{r=JSON.parse(i);}catch{return null}let s=r.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:i,sessionId:s,cleanupSharedState:e,executionId:n},u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let p=u.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),g=u.getWorkByIdempotencyKey(a);return {status:p.state==="closed"||p.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:g?.state??"pending",closureState:p.state,pendingWorkCount:p.pendingWorkCount}}catch(p){if(!o)throw p;return $e(t,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}async function ii(i,t=B(),e=true,n){let o;try{o=JSON.parse(i);}catch{return}let r=o.session_id?.trim();if(!r)return;let s=new L(t),a=s.get(r),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(b=>b.contractId)??[]},u=n?.telemetry??new G,p=!n?.telemetry,g=false,y;try{try{await u.flushAndAggregate();}catch{}let b=Date.now(),h=n?.executionId??a?.executionId,C;try{let m=openGlobalDevFlowDatabase();try{C=m.listSessionMemoryTurnsForReconciliation(t,r);for(let l of C){let f=`memory:${l.turnId}`,d=m.getSessionObligation(t,r,f);d?d.state==="open"&&l.status!=="pending"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:f,state:"satisfied",receiptId:l.receiptId,reason:l.reason,resolvedAt:l.decidedAt}):m.upsertSessionObligation({obligationId:f,projectRoot:t,sessionId:r,turnId:l.turnId,kind:"memory_decision",state:l.status==="pending"?"open":"satisfied",payload:{eventId:l.eventId,promptHash:l.promptHash},receiptId:l.receiptId,reason:l.reason,createdAt:l.createdAt,updatedAt:l.decidedAt??l.createdAt,resolvedAt:l.decidedAt});}}finally{m.close();}}catch(m){let l=D(m),f={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:l,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"turn_load",reason:l,metadata:f}),new I("turn_load",l)}let T=zt(C),_=n?.memory??(y=new MemoryGate(t)),q={status:"completed"};try{q=typeof _.reconcileTurnObservationLineage=="function"?{status:"completed",...await _.reconcileTurnObservationLineage(C)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(m){let l=D(m);throw q={status:"degraded",reason:l},N({projectRoot:t,sessionId:r,executionId:h,stage:"memory_lineage",reason:l,metadata:{...T,...c,memoryLineageReconciliation:q}}),new I("memory_lineage",l)}let H={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let m=Fe(o.transcript_path),l=openGlobalDevFlowDatabase(),f="unknown",d="no_terminal_host_action_evidence",U,F,M,Z=[];try{let X=l.listHostActionsForSession(t,r,h),oe=X.filter(v=>v.state==="verified"),Y=X.filter(v=>["failed","cancelled","degraded"].includes(v.state));Y.length>0?(f="negative",d=`terminal_host_action_${Y[0].state}`):oe.length>0&&(f="positive",d="host_action_verified");let J=Y[0]??oe.at(-1);if(U=J?.runId,F=J?.contextReceipt,M=J?.evidenceHash,Z=X.flatMap(v=>{let E=v.report.toolUseIds;return Array.isArray(E)?E.filter(z=>typeof z=="string"):[]}),!J&&h){let v=l.getSkillExecution(h),E=v?.metadata&&typeof v.metadata=="object"&&Array.isArray(v.metadata.policyVerificationOutcomes)?v.metadata.policyVerificationOutcomes:[],z=E.find(w=>w.status==="failed"),K=E.filter(w=>w.status==="passed");z?(f="negative",d="policy_verification_failed",M=typeof z.receiptId=="string"?z.receiptId:void 0):K.length>0&&(f="positive",d="policy_verification_passed",M=typeof K.at(-1)?.receiptId=="string"?String(K.at(-1).receiptId):void 0),F=l.getActiveContextReceipt(t,r,h)?.contextHash,Z=E.map(w=>w.command).filter(w=>typeof w=="string");}}finally{l.close();}let je=Me({projectRoot:t,sessionId:r,executionId:h,outcome:f,outcomeReason:d,verificationReceipt:M,finishedAt:b}),Le=await _.attributeRetrievalBenefits({sessionId:r,executionId:h,finalAnswer:m,outcome:f,outcomeReason:d,workflowRunId:U,contextReceipt:F,toolEvidence:Z,verificationReceipt:M});H={status:m?"evaluated":"unknown",...Le,retrievalLedger:je};}catch(m){H={...H,status:"degraded",reason:D(m)};}let R;try{R=await _.reconcileDecidedTurnEventWindows(r,C,b);}catch(m){let l=D(m),f={...T,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:l,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"event_reconciliation",reason:l,metadata:f}),new I("event_reconciliation",l)}let $;try{$=await ve({projectRoot:t,sessionId:r,trigger:"session_end",memory:_,details:{eventReconciliation:R},strictPersistence:!0});}catch(m){let l=D(m),f={...T,...c,memoryEventReconciliation:{status:"completed",...R,checkpointPending:null},memoryCheckpointDegradation:l};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"checkpoint",reason:l,metadata:f}),new I("checkpoint",l)}let re={memoryLineageReconciliation:q,memoryBenefitAttribution:H,memoryEventReconciliation:{status:"completed",...R,checkpointPending:$.pendingEvents},memoryDistillCheckpoint:$};try{let m=openGlobalDevFlowDatabase();try{let l=`session-finalize:${r}:events`,f=Math.max(Number($.pendingEvents??0),Number(R.remainingUndecided??0)),d=m.getSessionObligation(t,r,l);f>0?m.upsertSessionObligation({obligationId:l,projectRoot:t,sessionId:r,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:f,reconciliation:R,checkpointId:$.id},reason:"active_unprocessed_session_events",createdAt:d?.createdAt??b,updatedAt:b}):d?.state==="open"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:l,state:"satisfied",reason:"session_events_reconciled",resolvedAt:b});}finally{m.close();}}catch(m){console.error("[devflow] Session finalization obligation persistence failed:",m.message);}try{await _.closeSession(r),y&&(y.close(),y=void 0);}catch(m){let l=D(m),f={...T,...c,...re,memorySessionCloseDegradation:l};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"memory_close",reason:l,metadata:f}),new I("memory_close",l)}let P={...T,...c,...re};g=!0;let S;try{S=openGlobalDevFlowDatabase();let m=h;if(m)try{S.reconcileSkillExecution(m,"completed",b,P);let d=S.getSkillExecution(m);await j("/api/telemetry/skill-execution/complete",{executionId:m,finishedAt:b,status:"completed",summary:{totalToolCalls:d?.totalToolCalls??0,mcpToolCalls:d?.mcpToolCalls??0,directToolCalls:d?.directToolCalls??0,subagentCount:d?.subagentCount??0,totalDuration:d?.totalDuration??0,mcpComplianceRate:d?.mcpComplianceRate??0,missedTools:d?.missedMcpTools??[],actualFailureCount:d?.failedToolCalls??0,fallbackCount:d?.fallbackCount??0,fallbackReasons:d?.fallbackReasons??[]},metadata:P},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let l=S.reconcileRunningSkillExecutionsForSession(r,b,{closureReason:"session_finalize",...P});for(let d of l)await j("/api/telemetry/skill-execution/complete",{executionId:d.executionId,finishedAt:d.finishedAt,status:d.status,summary:{totalToolCalls:d.totalToolCalls??0,mcpToolCalls:d.mcpToolCalls??0,directToolCalls:d.directToolCalls??0,subagentCount:d.subagentCount??0,totalDuration:d.totalDuration??0,mcpComplianceRate:d.mcpComplianceRate??0,missedTools:d.missedMcpTools??[],actualFailureCount:d.failedToolCalls??0,fallbackCount:d.fallbackCount??0,fallbackReasons:d.fallbackReasons??[]},metadata:P},{fallbackReason:"skill_execution_already_reconciled_locally"});let f=S.getLatestSkillExecutionForSession(r);if(f&&!l.some(d=>d.executionId===f.executionId)&&S.mergeSkillExecutionMetadata(f.executionId,P),e){S.deleteHookReceipt(t);let d=k(t),U=createHash("sha256").update(t).digest("hex").slice(0,12);for(let F of [`session-id-${U}`,"current-execution-id","current-skill.json","event-map.json"])rmSync(join(d,F),{force:!0});}S.deleteContextReceipt(t,r);}catch{}finally{S?.close();}try{await u.endSession(r),await u.flushAndAggregate();}catch{}}finally{if(y)try{y.close();}catch{}p&&u.close(),g&&s.removeSession(r);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.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=jt(t.trim()||process.argv[2]||"");e&&i(JSON.stringify(e)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}export{zt as buildMemoryTurnOutcomeMetadata,jt as enqueueSessionEndFinalization,ii as handleSessionEnd};
|
|
1
|
+
import {getLocalApiKey,getProjectStateDir,resolveRuntimeEndpoint,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure}from'@devflow-tools/sdk';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {MemoryGate}from'@devflow-tools/memory-engine';import {existsSync as existsSync$1,readFileSync,rmSync as rmSync$1,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1,unlinkSync as unlinkSync$1}from'fs';import {join as join$1}from'path';import {homedir as homedir$1}from'os';import {request}from'node:http';import {mkdirSync,existsSync,writeFileSync,renameSync,unlinkSync,rmSync,lstatSync,openSync,constants,fstatSync,readSync,closeSync,appendFileSync}from'node:fs';import {join}from'node:path';import {homedir}from'node:os';import {createHash}from'node:crypto';import {randomUUID,createHash as createHash$1}from'crypto';function B(i){return i??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(i){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(B(i))}function Q(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 Ze=getLocalApiKey(),ee=join(homedir(),".devflow","errors");async function j(i,t,e={}){let n=e.endpoint??resolveRuntimeEndpoint().url,o=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),a=e.circuitBreaker??true,c=acquireRuntimeHttpCircuit(n,i);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let u;for(let g=0;g<=s;g+=1)try{return await Xe(n,i,t,o),a&®isterRuntimeHttpSuccess(n,i).transitioned&&Q("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(y){u=y instanceof Error?y:new Error(String(y)),g<s&&await Ye(Math.min(100*2**g,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return de(i,u),{delivered:false,suppressed:false,fallbackReason:u.message};let p=registerRuntimeHttpFailure(n,i,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return p.transitioned&&(de(i,u),Q("http_circuit_transition",{endpoint:n,path:new URL(i,n).pathname,previous:c.state.status,status:"open",failures:p.state.failures,openUntil:p.state.openUntil,fallbackReason:p.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:p.state.fallbackReason}}function Xe(i,t,e,n){return new Promise((o,r)=>{let s=JSON.stringify(e),a=new URL(t,i),c=false,u=g=>{c||(c=true,g?r(g):o());},p=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Ze,"Content-Length":Buffer.byteLength(s)},timeout:n},g=>{g.on("error",u),g.on("end",()=>{let y=g.statusCode??0;u(y>=200&&y<300?void 0:new Error(`HTTP ${y}`));}),g.resume();});p.on("error",u),p.on("timeout",()=>p.destroy(new Error(`HTTP mirror timed out after ${n}ms`))),p.write(s),p.end();})}function de(i,t){try{existsSync(ee)||mkdirSync(ee,{recursive:!0}),appendFileSync(join(ee,"http-errors.log"),`${new Date().toISOString()} | ${i} | ${t.message}
|
|
2
|
+
`);}catch{}}function Ye(i){return new Promise(t=>setTimeout(t,i))}var ye=1e4,nt=3e4,W=500,G=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=t?.legacyCacheDir??(t?.cacheDir?null:join$1(homedir$1(),".devflow","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 a={executionId:t,sessionId:e,skillName:n,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}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 n=this.getDatabase(),o=n.listTelemetryFailures({unresolvedOnly:!0,limit:W}).reverse();for(let r of o)try{this.applyOperation(r.operation,r.payload),n.resolveTelemetryFailure(r.id);}catch{}n.trimTelemetryFailures(W);}catch{}let e=[...new Set([this.cacheDir,this.legacyCacheDir].filter(n=>!!n))].filter(n=>existsSync$1(n)).flatMap(n=>readdirSync(n).filter(o=>o.endsWith(".json")).map(o=>{let r=join$1(n,o);try{return {cacheFile:r,envelope:it(JSON.parse(readFileSync(r,"utf8")),o)}}catch{return null}})).filter(n=>n!==null).sort((n,o)=>n.envelope.timestamp-o.envelope.timestamp||he(n.envelope.operation)-he(o.envelope.operation));for(let{cacheFile:n,envelope:o}of e)try{let r=this.getDatabase();r.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),r.resolveTelemetryFailure(o.id),unlinkSync$1(n);}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:be(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(be(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(W),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync$1(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync$1(s,JSON.stringify(r,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-W)))unlinkSync$1(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},nt).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){j(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ye?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ye)}...`}}};function he(i){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(i)}function be(i){return `hook-run:${i}`}function it(i,t){if(!i||typeof i!="object")throw new Error("Invalid telemetry cache envelope");let e=i;if(typeof e.operation=="string"&&e.payload!==void 0)return e;let n=e.type==="tool_call"?"tool_call":e.type==="execution_start"?"execution_start":null;if(!n)throw new Error("Unknown legacy telemetry cache operation");let o=e.payload??{},r=Number(o.timestamp??o.startedAt??Date.now());return {id:`legacy-cache:${t}`,operation:n,payload:o,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:r}}async function ve(i){let t=!i.memory,e=i.memory??new MemoryGate(i.projectRoot),n=0,o=0;try{await e.forceWarmUp(),i.trigger==="session_end"&&(n=await e.releasePendingDistillLeases(i.sessionId)),o=e.getPendingEventCount(i.sessionId,i.trigger!=="session_end");}finally{t&&e.close();}let r=Date.now(),s=i.trigger==="session_end"&&i.sessionId?`distill:session_end:${createHash("sha256").update(`${i.projectRoot}\0${i.sessionId}`).digest("hex").slice(0,24)}`:`distill:${r}:${Math.random().toString(36).slice(2,10)}`,a={id:s,pendingEvents:o,releasedLeases:n,trigger:i.trigger,sessionId:i.sessionId,details:i.details};try{let c=openGlobalDevFlowDatabase();try{c.recordMemoryDistillCheckpoint({id:s,projectRoot:i.projectRoot,sessionId:i.sessionId,trigger:i.trigger,pendingEvents:o,releasedLeases:n,details:i.details,createdAt:r}),c.insertEvent({kind:"memory_distill_requested",timestamp:r,success:!0,metadata:{...a,projectRoot:i.projectRoot}});}finally{c.close();}}catch(c){throw c}return a}function _e(i){return Buffer.from(i,"utf8").toString("base64url")}function dt(i,t,e){let n=t?.trim();if(n){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(n)?n:`tool-${createHash$1("sha256").update(n.slice(0,1024)).digest("hex").slice(0,32)}`;return `${i}:${o}`}return `${i}:legacy-${e}-${randomUUID().slice(0,8)}`}function De(i){return `${i}:legacy-journal`}var L=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(k(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let 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)],o.lastActivityAt=Date.now(),this.persist(o),o}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$1(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=ke(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,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),n}addEvidenceObligation(t,e,n=Date.now(),o){let r=this.registerSession(t),a=(o?void 0:r.evidenceObligations.find(u=>u.contractId===e.id))?.obligationId??dt(e.id,o,n);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:n,contract:e},`add\0${a}`),this.replayEvidenceJournal(r);let c=r.evidenceObligations.find(u=>u.obligationId===a);return c?(r.lastActivityAt=Date.now(),this.persist(r),structuredClone(c)):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),a=s?.evidenceObligations.find(p=>p.obligationId===e);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(o)?o:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:r,fingerprint:c,violations:n.slice(0,16).map(p=>p.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let u=s.evidenceObligations.find(p=>p.obligationId===e);return u?structuredClone(u):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}degradeEvidenceObligation(t,e,n,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(c=>c.obligationId===e);if(!r||!s)return false;let a=n.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:o,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(r),r.lastActivityAt=o,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync$1(this.snapshotPath(e),{force:true}),rmSync$1(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$1(o,{recursive:true,mode:448});let r=createHash$1("sha256").update(n).digest("hex"),s=join$1(o,`${e.kind}-${r}.json`);if(existsSync$1(s))return;let a=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(e),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync$1(a,{force:true});}}replayEvidenceJournal(t){t.evidenceObligations=Re(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=ke(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(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 a=ut(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||Ae(r.kind)-Ae(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(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let 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??0;t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),!n&&(e.kind==="degrade"&&t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r}),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$1(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),n=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(n,JSON.stringify(t),{mode:384}),renameSync$1(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)||!Oe(e.contract))return [];let n=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:De(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 ke(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 ut(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:De(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Oe(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 Ae(i){return i==="add"?0:i==="correction"?1:2}function Oe(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 $e(i,t){let e=yt(i);mkdirSync(e,{recursive:true,mode:448});let n=join(e,`${t.receiptId}.json`);if(existsSync(n))return t.receiptId;let o=`${n}.${process.pid}.tmp`;writeFileSync(o,JSON.stringify(t),{mode:384});try{renameSync(o,n);}catch(r){try{unlinkSync(o);}catch{}if(!existsSync(n))throw r}return t.receiptId}function yt(i){return join(k(i),"session-finalize-pending")}var wt=512*1024,_t=500;var Rt=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function Et(i){let t=false,e=[],n=[];for(let o of i){if(/^\s*```/.test(o)){t=!t,e.push(""),n.push(o.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}e.push(t?"":o.replace(/`[^`]*`/g,"").trim()),n.push(o.replace(/`([^`]*)`/g,(r,s)=>kt(s)?"":s).trim());}return {headingLines:e,claimLines:n}}function kt(i){let t=i.trim().slice(0,256);return !t||/\s/.test(t)||i.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(t)||/^(['"])[^'"`]*\1$/.test(t)}function At(i,t){if(!i||i.length>4096)return {degradationReason:"transcript_path_missing"};let e;try{let n=lstatSync(i);if(!n.isFile()||n.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};e=openSync(i,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let o=fstatSync(e);if(!o.isFile()||o.dev!==n.dev||o.ino!==n.ino)return {degradationReason:"transcript_path_changed"};let r=Math.min(o.size,wt),s=Buffer.alloc(r),a=0;for(;a<r;){let h=readSync(e,s,a,r-a,o.size-r+a);if(h===0)break;a+=h;}let c=s.subarray(0,a).toString("utf8");o.size>r&&(c=c.slice(Math.max(0,c.indexOf(`
|
|
3
|
+
`)+1)));let u=c.split(/\r?\n/).slice(-_t),p=t.length>0?Math.min(...t.map(h=>h.promptedAt)):0,g=Dt(u,p),b=[...g].reverse().find(h=>xt(h.text,t))??g.at(-1);return b?.text?{answer:b.text,fingerprint:b.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{e!==void 0&&closeSync(e);}}function xt(i,t){let e=new Set(t.flatMap(o=>o.contract.requiredSections)),n=Ct(Et(i.split(/\r?\n/u)).headingLines);return [...e].every(o=>n.found.has(o))}function Fe(i){return At(i,[]).answer}function Dt(i,t){let e=[];for(let n=0;n<i.length;n++){let o=i[n];if(o.trim())try{let r=JSON.parse(o),s=r.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=Ot(r.timestamp);if(c>0&&c+5e3<t)continue;let u=s.content,p=typeof u=="string"?u:Array.isArray(u)?u.filter(g=>g&&typeof g=="object"&&g.type==="text").map(g=>g.text).filter(g=>typeof g=="string").join(`
|
|
4
|
+
`):"";if(p.trim()){let g=p.trim(),y=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof r.uuid=="string"&&r.uuid?`uuid:${r.uuid}`:`record:${String(r.timestamp??"")}:${n}:${createHash("sha256").update(o).digest("hex")}`,b=createHash("sha256").update(g).digest("hex"),h=createHash("sha256").update(`${y}\0${b}`).digest("hex");e.push({text:g,timestamp:c,fingerprint:h});}}catch{continue}}return e}function Ot(i){if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i!="string")return 0;let t=Date.parse(i);return Number.isFinite(t)?t:0}function Ct(i){let t=new Set,e=new Map,n;for(let o=0;o<i.length;o++){let r=i[o].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=Rt.find(a=>r===a);s&&(n=s,t.add(s)),e.set(o,n);}return {found:t,byLine:e}}function ze(i){let t=openGlobalDevFlowDatabase();try{let e=t.listRetrievalLedgerEvents(i),n=new Map(e.filter(c=>c.stage==="selected").map(c=>[Me(c),c])),o=new Map(e.filter(c=>c.stage==="adopted").map(c=>[Me(c),c])),r=0,s=0,a=0;for(let[c,u]of n){let p=o.get(c),g=p&&i.verificationReceipt&&i.outcome!=="unknown"?i.outcome:"unknown",y=g==="positive"?"positive_outcome":g==="negative"?"negative_outcome":"unknown";t.appendRetrievalLedgerEvent({...u,id:Pt(u.id,y,i.verificationReceipt??i.sessionId),stage:y,reason:p?i.outcomeReason:"selected_not_adopted",toolEvidence:p?.toolEvidence??[],verificationReceipt:g==="unknown"?void 0:i.verificationReceipt,payload:{...u.payload,adopted:!!p},createdAt:i.finishedAt??Date.now()}),y==="positive_outcome"?r+=1:y==="negative_outcome"?s+=1:a+=1;}return {adopted:o.size,positive:r,negative:s,unknown:a}}finally{t.close();}}function Pt(i,t,e){return `retrieval:${createHash("sha256").update(`${i}\0${t}\0${e}`).digest("hex")}`}function Me(i){return [i.requestId,i.contextReceipt,i.sourceType,i.sourceId].join("\0")}function jt(i){let t={committed:0,skipped:0,pending:0},e=[];for(let n of i)t[n.status]+=1,n.receiptId&&e.push(n.receiptId);return {memoryReceiptIds:[...new Set(e)],missingMemoryDecisionCount:t.pending,memoryTurnOutcomes:t}}function D(i){return (i instanceof Error?i.message:String(i)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var w=class extends Error{constructor(t,e){super(`session_finalize_${t}:${e}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${t}`;}};function N(i){let t;try{t=openGlobalDevFlowDatabase();let e=(i.executionId?t.getSkillExecution(i.executionId):null)??t.getLatestSkillExecutionForSession(i.sessionId),n={stage:i.stage,reason:i.reason,degradedAt:Date.now()};e&&t.mergeSkillExecutionMetadata(e.executionId,{...i.metadata,sessionFinalizationDegradations:[n]}),t.insertEvent({kind:"session_finalize_degraded",timestamp:n.degradedAt,success:!1,metadata:{projectRoot:i.projectRoot,sessionId:i.sessionId,executionId:e?.executionId,...n}});}catch{}finally{t?.close();}}function Lt(i,t=B(),e=true,n,o=true){let r;try{r=JSON.parse(i);}catch{return null}let s=r.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${t}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:i,sessionId:s,cleanupSharedState:e,executionId:n},u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let p=u.requestSessionClosure({receiptId:a,projectRoot:t,sessionId:s,payload:c}),g=u.getWorkByIdempotencyKey(a);return {status:p.state==="closed"||p.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:g?.state??"pending",closureState:p.state,pendingWorkCount:p.pendingWorkCount}}catch(p){if(!o)throw p;return $e(t,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}async function ri(i,t=B(),e=true,n){let o;try{o=JSON.parse(i);}catch{return}let r=o.session_id?.trim();if(!r)return;let s=new L(t),a=s.get(r),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(b=>b.contractId)??[]},u=n?.telemetry??new G,p=!n?.telemetry,g=false,y;try{try{await u.flushAndAggregate();}catch{}let b=Date.now(),h=n?.executionId??a?.executionId,C;try{let m=openGlobalDevFlowDatabase();try{C=m.listSessionMemoryTurnsForReconciliation(t,r);for(let l of C){let f=`memory:${l.turnId}`,d=m.getSessionObligation(t,r,f);d?d.state==="open"&&l.status!=="pending"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:f,state:"satisfied",receiptId:l.receiptId,reason:l.reason,resolvedAt:l.decidedAt}):m.upsertSessionObligation({obligationId:f,projectRoot:t,sessionId:r,turnId:l.turnId,kind:"memory_decision",state:l.status==="pending"?"open":"satisfied",payload:{eventId:l.eventId,promptHash:l.promptHash},receiptId:l.receiptId,reason:l.reason,createdAt:l.createdAt,updatedAt:l.decidedAt??l.createdAt,resolvedAt:l.decidedAt});}}finally{m.close();}}catch(m){let l=D(m),f={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:l,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"turn_load",reason:l,metadata:f}),new w("turn_load",l)}let T=jt(C),_=n?.memory??(y=new MemoryGate(t)),q={status:"completed"};try{q=typeof _.reconcileTurnObservationLineage=="function"?{status:"completed",...await _.reconcileTurnObservationLineage(C)}:{status:"unsupported_adapter",committed:0,skipped:0,quarantined:0,unlinked:0};}catch(m){let l=D(m);throw q={status:"degraded",reason:l},N({projectRoot:t,sessionId:r,executionId:h,stage:"memory_lineage",reason:l,metadata:{...T,...c,memoryLineageReconciliation:q}}),new w("memory_lineage",l)}let H={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let m=Fe(o.transcript_path),l=openGlobalDevFlowDatabase(),f="unknown",d="no_terminal_host_action_evidence",U,F,M,Z=[];try{let X=l.listHostActionsForSession(t,r,h),oe=X.filter(v=>v.state==="verified"),Y=X.filter(v=>["failed","cancelled","degraded"].includes(v.state));Y.length>0?(f="negative",d=`terminal_host_action_${Y[0].state}`):oe.length>0&&(f="positive",d="host_action_verified");let J=Y[0]??oe.at(-1);if(U=J?.runId,F=J?.contextReceipt,M=J?.evidenceHash,Z=X.flatMap(v=>{let E=v.report.toolUseIds;return Array.isArray(E)?E.filter(z=>typeof z=="string"):[]}),!J&&h){let v=l.getSkillExecution(h),E=v?.metadata&&typeof v.metadata=="object"&&Array.isArray(v.metadata.policyVerificationOutcomes)?v.metadata.policyVerificationOutcomes:[],z=E.find(I=>I.status==="failed"),K=E.filter(I=>I.status==="passed");z?(f="negative",d="policy_verification_failed",M=typeof z.receiptId=="string"?z.receiptId:void 0):K.length>0&&(f="positive",d="policy_verification_passed",M=typeof K.at(-1)?.receiptId=="string"?String(K.at(-1).receiptId):void 0),F=l.getActiveContextReceipt(t,r,h)?.contextHash,Z=E.map(I=>I.command).filter(I=>typeof I=="string");}}finally{l.close();}let Le=ze({projectRoot:t,sessionId:r,executionId:h,outcome:f,outcomeReason:d,verificationReceipt:M,finishedAt:b}),Ne=await _.attributeRetrievalBenefits({sessionId:r,executionId:h,finalAnswer:m,outcome:f,outcomeReason:d,workflowRunId:U,contextReceipt:F,toolEvidence:Z,verificationReceipt:M});H={status:m?"evaluated":"unknown",...Ne,retrievalLedger:Le};}catch(m){H={...H,status:"degraded",reason:D(m)};}let R;try{R=await _.reconcileDecidedTurnEventWindows(r,C,b);}catch(m){let l=D(m),f={...T,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:l,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"event_reconciliation",reason:l,metadata:f}),new w("event_reconciliation",l)}let $;try{$=await ve({projectRoot:t,sessionId:r,trigger:"session_end",memory:_,details:{eventReconciliation:R},strictPersistence:!0});}catch(m){let l=D(m),f={...T,...c,memoryEventReconciliation:{status:"completed",...R,checkpointPending:null},memoryCheckpointDegradation:l};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"checkpoint",reason:l,metadata:f}),new w("checkpoint",l)}let re={memoryLineageReconciliation:q,memoryBenefitAttribution:H,memoryEventReconciliation:{status:"completed",...R,checkpointPending:$.pendingEvents},memoryDistillCheckpoint:$};try{let m=openGlobalDevFlowDatabase();try{let l=`session-finalize:${r}:events`,f=Math.max(Number($.pendingEvents??0),Number(R.remainingUndecided??0)),d=m.getSessionObligation(t,r,l);f>0?m.upsertSessionObligation({obligationId:l,projectRoot:t,sessionId:r,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:f,reconciliation:R,checkpointId:$.id},reason:"active_unprocessed_session_events",createdAt:d?.createdAt??b,updatedAt:b}):d?.state==="open"&&m.resolveSessionObligation({projectRoot:t,sessionId:r,obligationId:l,state:"satisfied",reason:"session_events_reconciled",resolvedAt:b});}finally{m.close();}}catch(m){console.error("[devflow] Session finalization obligation persistence failed:",m.message);}try{await _.closeSession(r),y&&(y.close(),y=void 0);}catch(m){let l=D(m),f={...T,...c,...re,memorySessionCloseDegradation:l};throw N({projectRoot:t,sessionId:r,executionId:h,stage:"memory_close",reason:l,metadata:f}),new w("memory_close",l)}let P={...T,...c,...re};g=!0;let S;try{S=openGlobalDevFlowDatabase();let m=h;if(m)try{S.reconcileSkillExecution(m,"completed",b,P);let d=S.getSkillExecution(m);await j("/api/telemetry/skill-execution/complete",{executionId:m,finishedAt:b,status:"completed",summary:{totalToolCalls:d?.totalToolCalls??0,mcpToolCalls:d?.mcpToolCalls??0,directToolCalls:d?.directToolCalls??0,subagentCount:d?.subagentCount??0,totalDuration:d?.totalDuration??0,mcpComplianceRate:d?.mcpComplianceRate??0,missedTools:d?.missedMcpTools??[],actualFailureCount:d?.failedToolCalls??0,fallbackCount:d?.fallbackCount??0,fallbackReasons:d?.fallbackReasons??[]},metadata:P},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let l=S.reconcileRunningSkillExecutionsForSession(r,b,{closureReason:"session_finalize",...P});for(let d of l)await j("/api/telemetry/skill-execution/complete",{executionId:d.executionId,finishedAt:d.finishedAt,status:d.status,summary:{totalToolCalls:d.totalToolCalls??0,mcpToolCalls:d.mcpToolCalls??0,directToolCalls:d.directToolCalls??0,subagentCount:d.subagentCount??0,totalDuration:d.totalDuration??0,mcpComplianceRate:d.mcpComplianceRate??0,missedTools:d.missedMcpTools??[],actualFailureCount:d.failedToolCalls??0,fallbackCount:d.fallbackCount??0,fallbackReasons:d.fallbackReasons??[]},metadata:P},{fallbackReason:"skill_execution_already_reconciled_locally"});let f=S.getLatestSkillExecutionForSession(r);if(f&&!l.some(d=>d.executionId===f.executionId)&&S.mergeSkillExecutionMetadata(f.executionId,P),e){S.deleteHookReceipt(t);let d=k(t),U=createHash("sha256").update(t).digest("hex").slice(0,12);for(let F of [`session-id-${U}`,"current-execution-id","current-skill.json","event-map.json"])rmSync(join(d,F),{force:!0});}S.deleteContextReceipt(t,r);}catch{}finally{S?.close();}try{await u.endSession(r),await u.flushAndAggregate();}catch{}}finally{if(y)try{y.close();}catch{}p&&u.close(),g&&s.removeSession(r);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.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=Lt(t.trim()||process.argv[2]||"");e&&i(JSON.stringify(e)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}export{jt as buildMemoryTurnOutcomeMetadata,Lt as enqueueSessionEndFinalization,ri as handleSessionEnd};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.33",
|
|
4
4
|
"description": "DevFlow — Developer Intelligence Platform for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "npx tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.16.
|
|
16
|
-
"@devflow-tools/context-engine": "0.16.
|
|
17
|
-
"@devflow-tools/database": "0.16.
|
|
18
|
-
"@devflow-tools/memory-engine": "0.16.
|
|
19
|
-
"@devflow-tools/sdk": "0.16.
|
|
20
|
-
"@devflow-tools/server": "0.16.
|
|
21
|
-
"@devflow-tools/telemetry": "0.16.
|
|
22
|
-
"@devflow-tools/workflow-engine": "0.16.
|
|
15
|
+
"@devflow-tools/benchmark": "0.16.33",
|
|
16
|
+
"@devflow-tools/context-engine": "0.16.33",
|
|
17
|
+
"@devflow-tools/database": "0.16.33",
|
|
18
|
+
"@devflow-tools/memory-engine": "0.16.33",
|
|
19
|
+
"@devflow-tools/sdk": "0.16.33",
|
|
20
|
+
"@devflow-tools/server": "0.16.33",
|
|
21
|
+
"@devflow-tools/telemetry": "0.16.33",
|
|
22
|
+
"@devflow-tools/workflow-engine": "0.16.33"
|
|
23
23
|
},
|
|
24
24
|
"allowScripts": {
|
|
25
25
|
"better-sqlite3@12.11.1": true,
|
|
26
26
|
"sharp@0.32.6": true
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@devflow-tools/mcp-server": "0.16.
|
|
29
|
+
"@devflow-tools/mcp-server": "0.16.33"
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"pi-package",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/cli",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,31 +12,31 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@colbymchenry/codegraph": "^1.1.1",
|
|
15
|
-
"@devflow-tools/adapters": "0.16.
|
|
16
|
-
"@devflow-tools/benchmark": "0.16.
|
|
17
|
-
"@devflow-tools/context-engine": "0.16.
|
|
18
|
-
"@devflow-tools/database": "0.16.
|
|
19
|
-
"@devflow-tools/knowledge-engine": "0.16.
|
|
20
|
-
"@devflow-tools/mcp-server": "0.16.
|
|
21
|
-
"@devflow-tools/memory-engine": "0.16.
|
|
22
|
-
"@devflow-tools/plugin-animation": "0.16.
|
|
23
|
-
"@devflow-tools/plugin-css": "0.16.
|
|
24
|
-
"@devflow-tools/plugin-docker": "0.16.
|
|
25
|
-
"@devflow-tools/plugin-electron": "0.16.
|
|
26
|
-
"@devflow-tools/plugin-git": "0.16.
|
|
27
|
-
"@devflow-tools/plugin-graphql": "0.16.
|
|
28
|
-
"@devflow-tools/plugin-nest": "0.16.
|
|
29
|
-
"@devflow-tools/plugin-nextjs": "0.16.
|
|
30
|
-
"@devflow-tools/plugin-performance": "0.16.
|
|
31
|
-
"@devflow-tools/plugin-react": "0.16.
|
|
32
|
-
"@devflow-tools/plugin-tailwind": "0.16.
|
|
33
|
-
"@devflow-tools/plugin-taro": "0.16.
|
|
34
|
-
"@devflow-tools/plugin-ui-layout": "0.16.
|
|
35
|
-
"@devflow-tools/plugin-vue": "0.16.
|
|
36
|
-
"@devflow-tools/sdk": "0.16.
|
|
37
|
-
"@devflow-tools/server": "0.16.
|
|
38
|
-
"@devflow-tools/telemetry": "0.16.
|
|
39
|
-
"@devflow-tools/workflow-engine": "0.16.
|
|
15
|
+
"@devflow-tools/adapters": "0.16.33",
|
|
16
|
+
"@devflow-tools/benchmark": "0.16.33",
|
|
17
|
+
"@devflow-tools/context-engine": "0.16.33",
|
|
18
|
+
"@devflow-tools/database": "0.16.33",
|
|
19
|
+
"@devflow-tools/knowledge-engine": "0.16.33",
|
|
20
|
+
"@devflow-tools/mcp-server": "0.16.33",
|
|
21
|
+
"@devflow-tools/memory-engine": "0.16.33",
|
|
22
|
+
"@devflow-tools/plugin-animation": "0.16.33",
|
|
23
|
+
"@devflow-tools/plugin-css": "0.16.33",
|
|
24
|
+
"@devflow-tools/plugin-docker": "0.16.33",
|
|
25
|
+
"@devflow-tools/plugin-electron": "0.16.33",
|
|
26
|
+
"@devflow-tools/plugin-git": "0.16.33",
|
|
27
|
+
"@devflow-tools/plugin-graphql": "0.16.33",
|
|
28
|
+
"@devflow-tools/plugin-nest": "0.16.33",
|
|
29
|
+
"@devflow-tools/plugin-nextjs": "0.16.33",
|
|
30
|
+
"@devflow-tools/plugin-performance": "0.16.33",
|
|
31
|
+
"@devflow-tools/plugin-react": "0.16.33",
|
|
32
|
+
"@devflow-tools/plugin-tailwind": "0.16.33",
|
|
33
|
+
"@devflow-tools/plugin-taro": "0.16.33",
|
|
34
|
+
"@devflow-tools/plugin-ui-layout": "0.16.33",
|
|
35
|
+
"@devflow-tools/plugin-vue": "0.16.33",
|
|
36
|
+
"@devflow-tools/sdk": "0.16.33",
|
|
37
|
+
"@devflow-tools/server": "0.16.33",
|
|
38
|
+
"@devflow-tools/telemetry": "0.16.33",
|
|
39
|
+
"@devflow-tools/workflow-engine": "0.16.33",
|
|
40
40
|
"@inquirer/prompts": "^7.10.1",
|
|
41
41
|
"chalk": "^5.3.0",
|
|
42
42
|
"commander": "^12.0.0"
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"dist",
|
|
50
50
|
"bin"
|
|
51
51
|
],
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "59cf9c3f527a721757bab1af0d8b2732b1567845"
|
|
53
53
|
}
|