@devflow-tools/claude-code-plugin 0.19.0 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/command-registry.json +7 -7
- package/dist/hooks/hook-daemon.js +28 -27
- package/dist/hooks/pre-tool-use.js +5 -4
- package/dist/runtime-manifest.json +7 -7
- package/hooks/README.md +15 -0
- package/hooks/hooks.json +8 -24
- package/package.json +14 -14
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {createHash as createHash$1}from'node:crypto';import {existsSync as existsSync$1,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function M(n,t,e){try{let
|
|
2
|
-
`;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(i)}),appendFileSync(e,i);}catch{}}function ft(n){return new Promise(t=>setTimeout(t,n))}var pe=1e4,_t=3e4,U=500,H=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,i,o,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:i,startedAt:o,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",i=Date.now(),o){let r={executionId:t,status:e,finishedAt:i,metadata:o},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,i){let o={id:t,projectRoot:e,startedAt:i,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 i={sessionId:t,finishedAt:e},o=this.commitOrCache("session_end",i);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),o}async flushCache(){try{let e=this.getDatabase(),i=e.listTelemetryFailures({unresolvedOnly:!0,limit:U}).reverse();for(let o of i)try{this.applyOperation(o.operation,o.payload),e.resolveTelemetryFailure(o.id);}catch{}e.trimTelemetryFailures(U);}catch{}let t=(existsSync$1(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let i=join$1(this.cacheDir,e);try{return {cacheFile:i,envelope:Rt(JSON.parse(readFileSync(i,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,i)=>e.envelope.timestamp-i.envelope.timestamp||ge(e.envelope.operation)-ge(i.envelope.operation));for(let{cacheFile:e,envelope:i}of t)try{let o=this.getDatabase();o.insertTelemetryFailure({id:i.id,operation:i.operation,payload:i.payload,error:i.failure,createdAt:i.timestamp}),this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(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:fe(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!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(fe(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 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:i,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,i){let o=Date.now(),r={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:i instanceof Error?i.message:String(i),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:o}),s.trimTelemetryFailures(U),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-U)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},_t).unref());}scheduleMetricAggregation(){if(this.metricAggregationScheduled||process.env.DEVFLOW_HOOK_DEGRADED==="1")return;this.metricAggregationScheduled=true,setTimeout(()=>{this.metricAggregationScheduled=false;try{this.getDatabase().aggregatePendingToolMetrics(50)===50&&this.scheduleMetricAggregation();}catch{}},25).unref();}postHttp(t,e){ce(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=pe?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,pe)}...`}}};function ge(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function fe(n){return `hook-run:${n}`}function Rt(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function F(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function D(n){return getProjectStateDir(F(n))}var v=emitSemanticControlLog;var St=2,Ot=1;function At(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function me(n=At()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync$1(e))continue;let i=JSON.parse(readFileSync(e,"utf8"));if(i.version!==St&&i.version!==Ot||!Ct(i.commands)){v({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return i.commands}catch(i){v({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:i.message,fallback:"next_registry_candidate"}});}return null}function Ct(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 q(e.mcpTools)&&q(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||q(e.runtimePackages))&&(e.hostTools===void 0||Tt(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Tt(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&q(e))}function q(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function he(n){let t=me();return t?t[n]?.mcpTools??[]:[]}function _e(n){return Buffer.from(n,"utf8").toString("base64url")}function Pt(n,t,e){let i=t?.trim();if(i){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(i)?i:`tool-${createHash("sha256").update(i.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function ke(n){return `${n}:legacy-journal`}var S=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(D(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 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,i){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(i)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(t,e){let i=this.registerSession(t);return i.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},i.lastActivityAt=Date.now(),this.persist(i),i}completeContextInitialization(t,e){let i=this.get(t);return i?(e&&i.contextInitialization?.toolUseId&&i.contextInitialization.toolUseId!==e||(delete i.contextInitialization,i.lastActivityAt=Date.now(),this.persist(i)),i):null}bindTaskIdentity(t,e){let i=this.registerSession(t);return i.activeTurnId=e.turnId,i.activeRequestId=e.requestId,i.intentArtifactHash=e.intentArtifactHash,i.lastActivityAt=Date.now(),this.persist(i),i}get(t){let e=t.trim();if(!e)return null;let i=this.sessions.get(e);if(i)return this.replayEvidenceJournal(i),i;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=we(r.evidenceDegradations),r.evidenceOutcomes=Ee(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 i=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),i}addEvidenceObligation(t,e,i=Date.now(),o){let r=this.registerSession(t),a=(o?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Pt(e.id,o,i);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:i,contract:e},`add\0${a}`),this.replayEvidenceJournal(r);let c=r.evidenceObligations.find(l=>l.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,i,o,r=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(o)?o:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:r,fingerprint:c,violations:i.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let i=this.get(t);if(!i)return false;let o=i.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(i),i.lastActivityAt=r,this.persist(i),true}resolveDegradedEvidence(t,e){let i=this.get(t),o=i?.evidenceDegradations.find(s=>s.obligationId===e);if(!i||!o)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:o.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}degradeEvidenceObligation(t,e,i,o=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(c=>c.obligationId===e);if(!r||!s)return false;let a=i.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(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${_e(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",_e(t))}appendEvidenceEvent(t,e,i){let o=this.evidenceJournalDir(t);mkdirSync(o,{recursive:true,mode:448});let r=createHash("sha256").update(i).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(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=Re(t.evidenceObligations),t.evidenceDegradations=we(t.evidenceDegradations),t.evidenceOutcomes=Ee(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(e))return;let i;try{i=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let o=i.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=$t(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||De(r.kind)-De(s.kind));for(let r of o)this.applyEvidenceEvent(t,r);t.evidenceObligations=t.evidenceObligations.slice(-8),t.evidenceDegradations=t.evidenceDegradations.slice(-20),t.evidenceOutcomes=t.evidenceOutcomes.slice(-20);}applyEvidenceEvent(t,e){let 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 o=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!o||i||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??i?.attempt??0;if(e.kind==="resolve"&&i?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(i)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:o?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),i=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(i,JSON.stringify(t),{mode:384}),renameSync(i,e);}};function Re(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)||!Ie(e.contract))return [];let i=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:ke(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:i,correctionFingerprint:r}]}).slice(-8):[]}function we(n){return Array.isArray(n)?n.filter(t=>{if(!t||typeof t!="object")return false;let e=t;return typeof e.obligationId=="string"&&typeof e.contractId=="string"&&typeof e.reason=="string"&&typeof e.degradedAt=="number"&&typeof e.attempt=="number"}).slice(-20):[]}function Ee(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 $t(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 o={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:ke(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Ie(t.contract)?{kind:e,...o,contract:t.contract}:null;if(e==="correction"){let r=typeof t.fingerprint=="string"?t.fingerprint:t.transcriptHash;return typeof r=="string"&&/^[a-f0-9]{64}$/.test(r)&&Array.isArray(t.violations)&&t.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:e,...o,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...o}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...o,reason:t.reason}:null}function De(n){return n==="add"?0:n==="correction"?1:2}function Ie(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(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 B(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 o=t[i];if(o==null)continue;e[i]=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;}return e}function Mt(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function Se(n,t,e){let i=e instanceof Error?e.message:String(e);v({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:i,fallback:"fail_open"}});}function Oe(n,t,e){let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o={},r=i.updateHookReceipt(n,a=>(o=B(a),B(t(o)))),s=B(r);return {receipt:s,applied:!0,changed:!Mt(o,s)}}catch(o){return Se(n,e,o),{receipt:{},applied:false,changed:false}}finally{try{i?.close();}catch{}}}function Ae(n){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),B(t.getHookReceipt(n))}catch(e){return Se(n,"update",e),{}}finally{try{t?.close();}catch{}}}function Nt(n,t){return Oe(n,()=>t,"write").applied}function Ut(n,t){return Oe(n,t,"update")}var Z={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Ht=new Set(["Write","Edit","NotebookEdit"]),qt=new Set(["failed","timeout","unavailable"]);function Jt(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 W=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 i=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(i&&i.expiresAt>Date.now())return "context_ready";i&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new S(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let i=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(i==="context_initializing"&&Z[t])return {permissionDecision:"allow",additionalContext:`DevFlow context initialization is in progress; wait for ${projectClaudeToolName("get_project_context")} to complete before broad discovery with ${t}.`};if(i==="context_gathering"&&Z[t])return {permissionDecision:"allow",additionalContext:`DevFlow tip: call ${projectClaudeToolName("get_project_context")} first for scoped context instead of broad ${t} discovery.`};if(i==="context_ready"){if(Ht.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let o=Z[t];if(!o)return {permissionDecision:"allow"};let r=Ut(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,a=Jt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(o)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){Nt(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,i,o){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=o?.trim()?`${o.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||o&&d.toolUseId===o&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:o,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{r?.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 ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let o=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&qt.has(r.status));if(o.length>0){let r=o.at(-1),s={missedTool:e.tool,failedAttemptCount:o.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let i;try{i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=i.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!o||o.contextHash!==t.contextHash||o.actionDegradation)return;i.upsertContextReceipt({...o,actionDegradation:e});let r=i.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];i.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{i?.close();}catch{}}}};var Xt=10*1024*1024,Zt=5;function en(n){return createHash$1("sha256").update(n).digest("hex").slice(0,16)}function Ce(n){return join(homedir(),".devflow","logs","hook-debug",`${en(n)}.jsonl`)}function Te(n,t,e={}){let i=e.maxBytes??Xt,o=e.maxFiles??Zt;mkdirSync$1(dirname(n),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:n,maxBytes:i,maxFiles:o,incomingBytes:r}),appendFileSync(n,t,{mode:384}),chmodSync(n,384);}var ee="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Fe(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Le(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 je(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 sn=new Set(["Write","Edit","NotebookEdit"]),Pe=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function He(n){if(!sn.has(n.toolName))return null;let t=an(n.toolInput);if(!t)return null;let e=cn(t,n.projectRoot),i=resolve(n.projectRoot,".claude");if($e(e,i)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Pe;let o=resolve(n.home??homedir(),".claude","projects");return $e(e,o)&&relative(o,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Pe:null}function an(n){for(let t of ["file_path","notebook_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function cn(n,t){return resolve(isAbsolute(n)?n:resolve(t,n))}function $e(n,t){let e=relative(t,n);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function We(n){let t=hn(n.toolName,n.toolInput),e=t?yn(n.projectRoot,n.toolName,n.toolInput):void 0;if(!t||!e||!n.toolUseId)return {allowed:true};let i=bn(e),o,r=0,s,a;try{a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=a.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);o=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(d=>_n(n.projectRoot,d.path,e));}catch{}finally{try{a?.close();}catch{}}let c={toolUseId:n.toolUseId,sessionId:n.sessionId,executionId:n.executionId,operation:t,path:e,before:i,contextReceipt:o,observedAt:Date.now()};if(En(n.projectRoot,c),t==="edit"||t==="write"||t==="delete"){let l=Dn(n.projectRoot,e),d=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,u=s?.expectedState==="existing"&&!i.exists||s?.expectedState==="missing"&&i.exists||!!(s?.contentHash&&i.hash!==s.contentHash);if(d||s?.expectedState==="existing"&&!i.exists)return qe(n,c,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(u)return qe(n,c,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return Ve(n,c,true),{allowed:true,pending:c}}function qe(n,t,e,i){return Ve(n,t,false,e),{allowed:false,reasonCode:e,reason:i,pending:t}}function Ve(n,t,e,i){v({event:"canonical.action.validated",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(n.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:i,toolUseId:t.toolUseId}});}function hn(n,t){if(n==="Read")return "read";if(n==="Edit"||n==="NotebookEdit")return "edit";if(n==="Write")return "write";if(n==="Delete"||n==="Bash"&&ze(t.command))return "delete"}function yn(n,t,e){let i=vn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?ze(e.command):void 0);if(!i)return;let o=isAbsolute(i)?normalize(i):resolve(n,i),r=relative(n,o);return r.startsWith("..")||isAbsolute(r)?void 0:o}function ze(n){return typeof n!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(n)?.[2]}function vn(n,t){for(let e of t){let i=n[e];if(typeof i=="string"&&i.trim())return i.trim()}}function bn(n){if(!existsSync(n))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(n)).digest("hex")}}catch{return {exists:true}}}function _n(n,t,e){return (isAbsolute(t)?normalize(t):resolve(n,t))===normalize(e)}function Ge(n){return join(D(n),"file-state")}function Ke(n){return join(Ge(n),"pending.json")}function Rn(n){return join(Ge(n),"observations.jsonl")}function wn(n){try{return JSON.parse(readFileSync$1(Ke(n),"utf8"))}catch{return {}}}function En(n,t){let e=Ke(n);mkdirSync$1(dirname(e),{recursive:true});let i=wn(n);i[t.toolUseId]=t,xn(e,JSON.stringify(i));}function Dn(n,t){try{let e=readFileSync$1(Rn(n),"utf8").trim().split(`
|
|
3
|
-
`);for(let i=e.length-1;i>=0;i-=1){let o=JSON.parse(e[i]);if(o.path===t)return o}}catch{}}function xn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var On=new Set(["delivered","cancelled","rejected"]),An=new Set(["cancelled","rejected"]),Cn=new Set(["Write","Edit","NotebookEdit","Bash"]);function Tn(n,t){if(n!=="Bash"||typeof t?.command!="string")return false;let e=t.command.trim(),o="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${o}(?: \\|\\| ${o})*$`,"u").test(e)?true:/[;&|<>`$()]|\\/u.test(e)?false:/^(?:ls|pwd|find|rg|grep|cat|sed|head|tail|wc)(?:\s|$)/u.test(e)||/^git\s+(?:show|status|diff|log|branch)(?:\s|$)/u.test(e)}function re(n,t,e,i,o){if(e.includes("delivery_rebind_session")||!Cn.has(e)||!t.trim()||Tn(e,o))return null;let r=join(n,".devflow","delivery-line","state.db");if(!existsSync(r))return null;let s;try{s=new DatabaseSync(r,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let f=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let g of f){let b=[];try{b=JSON.parse(g.aliases);}catch{}(g.source_path===n||b.includes(n))&&c.add(g.case_id);}}let d=[];for(let f of a){let g=JSON.parse(f.payload),b=c.has(f.id);(g.sessionId===t||t===f.id||b)&&d.push({id:f.id,payload:g,updatedAt:typeof f.updated_at=="number"?f.updated_at:typeof g.updatedAt=="number"?g.updatedAt:0});let h=typeof g.stage=="string"?g.stage:"unknown";if(!On.has(h)){if(i&&h==="executing"){let m=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(f.id,Date.now()),_=typeof g.sessionId=="string"?g.sessionId:void 0,j=typeof g.executionId=="string"?g.executionId:void 0,k=i===m?.id||i===m?.lease_owner||i===j,P=t===f.id||t===_;if(m?.id&&k&&P)return null}if(g.sessionId===t||t===f.id||b)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:f.id,stage:h,message:`Delivery case ${f.id} is ${h}; use the Delivery task lease before modifying files.`}}}let u=d.sort((f,g)=>g.updatedAt-f.updatedAt)[0],p=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&p&&An.has(p)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:p,message:`Delivery case ${u.id} is ${p}; start a new Delivery case or session before modifying files.`}:null}catch(a){return v({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"delivery_authority",operation:"delivery_write_block",reason:a instanceof Error?a.message:String(a),fallback:"fail_open_unverified_write"}}),null}finally{s?.close();}}function Ye(n=process.env){if(n.DEVFLOW_DISABLED==="1")return true;try{return existsSync(join(getDevFlowStateRoot({env:n}),"disable"))}catch{return false}}function C(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function z(n){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:n}}}function Jn(n){let t=D(n);return existsSync$1(t)||mkdirSync(t,{recursive:true}),t}function Bn(n,t,e,i,o,r){let s=join$1(Jn(n),"event-map.json"),a=[];try{existsSync$1(s)&&(a=JSON.parse(readFileSync(s,"utf-8")));}catch{}a.push({sessionId:t,toolName:e,toolUseId:i,eventId:o,timestamp:r}),a.length>1e3&&a.splice(0,a.length-1e3),writeFileSync(s,JSON.stringify(a));}function Wn(n){switch(n){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function Vn(n,t,e){if(t!=="Read"||typeof e.file_path!="string"||!e.file_path.trim())return null;let i=e.file_path.startsWith("/")?e.file_path:join$1(n,e.file_path);try{if(statSync(i).isDirectory())return `Read accepts files, but "${e.file_path}" is a directory. Use Glob or Bash ls to inspect directory entries, then Read one file.`}catch{return null}return null}function zn(){let n=process.env.CLAUDE_PLUGIN_ROOT;if(!n)return null;let t=join$1(n,"package.json"),e=join$1(n,".mcp.json");try{let i=JSON.parse(readFileSync(t,"utf8")),r=JSON.parse(readFileSync(e,"utf8")).mcpServers?.devflow,s=r?.args;if(r?.command==="node"&&Array.isArray(s)&&s[0]==="${CLAUDE_PLUGIN_ROOT}/node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs")return existsSync$1(join$1(n,"node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs"))?null:"bundled DevFlow MCP runtime is not installed";let c=Array.isArray(s)?s.indexOf("--package"):-1,l=c>=0&&typeof s?.[c+1]=="string"?s[c+1]:void 0,d=typeof i.version=="string"?`@devflow-tools/mcp-server@${i.version}`:void 0;return l?d&&l!==d?`DevFlow MCP version mismatch (${l} vs ${d})`:null:"DevFlow MCP package configuration is missing"}catch{return "DevFlow MCP configuration could not be inspected"}}function Gn(){let n=process.env.CLAUDE_PLUGIN_ROOT?.trim();if(!n)return null;try{let t=join$1(n,"dist","runtime-manifest.json"),e=JSON.parse(readFileSync(t,"utf8")),i=typeof e.bundleHashes?.mcp=="string"?e.bundleHashes.mcp:void 0,o=join$1(n,"node_modules","@devflow-tools","mcp-server","dist","delivery-tools.js"),r=existsSync$1(o)?createHash$1("sha256").update(readFileSync(o)).digest("hex"):"missing";return !i||i!==r?"DevFlow runtime build does not match the active plugin manifest":null}catch{return "DevFlow runtime manifest is missing or invalid"}}function Kn(n,t,e){return new Set(["Write","Edit","NotebookEdit"]).has(n)?true:n==="Bash"?!Qe(n,t):!!(e?.startsWith("delivery_")&&e!=="delivery_status")}function Qe(n,t){return n==="Grep"||n==="Glob"?true:n!=="Bash"||typeof t.command!="string"?false:/^(?:ls|pwd|find|rg|grep|git\s+(?:status|diff|log|branch)|cat|sed|head|tail|wc)\b/u.test(t.command.trim())}async function Yn(n){if(Ye())return C();let t=Fe();try{if(!n||n.trim()==="")return C();let e=JSON.parse(n),i=Date.now();try{maybeRunDiagnosticLogCleanup(F(),{now:i});}catch{}let o=F(),r=new H,s=resolveClaudeToolName(e.tool_name,e.tool_input),a=s.status==="unsupported"?void 0:s.canonicalName;a&&(typeof e.tool_input.projectRoot!="string"||!e.tool_input.projectRoot.trim())&&(e.tool_input.projectRoot=o);let c=e.session_id?.trim();if(!c)return z(ee);let l=new S(o),d=l.get(c)!==null;if(l.registerSession(c),d||await r.sendSessionStart(c,o,Date.now()),e.tool_name==="Skill"){let R=e.tool_input?.skill,y=R?Le(R):null;if(y){let E=l.get(c)?.executionId,w=l.startExecution(c,y,he(y));w.executionId&&w.executionId!==E&&await r.sendExecutionStart(w.executionId,c,y,w.lastActivityAt,o,w.requiredMcpTools);}}let u=l.get(c);a==="get_project_context"&&l.beginContextInitialization(c,e.tool_use_id),a&&(e.tool_input._devflow_session_id=c,e.tool_input._devflow_execution_id=u?.executionId??c,u?.activeTurnId&&(e.tool_input._devflow_turn_id=u.activeTurnId),u?.activeRequestId&&(e.tool_input._devflow_request_id=u.activeRequestId),u?.intentArtifactHash&&(e.tool_input._devflow_intent_artifact_hash=u.intentArtifactHash),u?.skillName&&(e.tool_input._devflow_active_skill=u.skillName),e.tool_use_id&&(e.tool_input._devflow_tool_use_id=e.tool_use_id));let p=e.tool_name.startsWith("mcp__"),f=a,g=l.get(c),b=new W(o,c,g?.executionId),h=b.getPhase(),m,_,j=Vn(o,e.tool_name,e.tool_input),k=re(o,c,e.tool_name,g?.executionId,e.tool_input),P=!k&&Kn(e.tool_name,e.tool_input,f)?Gn():null;if(P)m=z(`DevFlow runtime build mismatch: ${P}. Refresh the plugin installation before relying on delivery_* results; file edits remain allowed.`);else if(j)_="DEVFLOW_DIRECTORY_READ_INVALID",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:j}};else if(k)_=k.code,m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${k.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}};else {let R=He({toolName:e.tool_name,toolInput:e.tool_input,projectRoot:o}),y=We({projectRoot:o,sessionId:c,executionId:g?.executionId,toolUseId:e.tool_use_id,toolName:e.tool_name,toolInput:e.tool_input}),E=R?{permissionDecision:"deny",reason:R}:y.allowed?b.evaluate(e.tool_name,p):{permissionDecision:"deny",reason:y.reason,reasonCode:y.reasonCode},w=!p&&Qe(e.tool_name,e.tool_input)&&(h==="context_gathering"||h==="context_initializing")?zn():null;w?(m=z(`DevFlow MCP is unavailable or stale: ${w}. This read-only fallback is temporary; refresh the plugin installation and call ${projectClaudeToolName("get_project_context")} before editing.`),_=void 0):E.permissionDecision==="deny"?(_=R?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":E.reasonCode??"DEVFLOW_CONTEXT_REQUIRED",m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:E.reason??"MCP context required"}}):E.additionalContext?m=z(E.additionalContext):m=C();}a&&(m.hookSpecificOutput.updatedInput=e.tool_input),t&&m.hookSpecificOutput.permissionDecision==="allow"&&(m.hookSpecificOutput.additionalContext=ee);let Xe=g?.executionId??c,T={eventId:je(c,e.tool_use_id),executionId:Xe,sessionId:c,projectRoot:o,toolUseId:e.tool_use_id,timestamp:Date.now(),toolName:e.tool_name,toolType:p?"mcp":e.tool_name==="Agent"?"subagent":"direct",isMcpTool:p,mcpToolName:f,mcpEnforced:p&&(h==="context_gathering"||h==="context_initializing"),mcpFallback:!p&&(h==="context_gathering"||h==="context_initializing"),kind:Wn(e.tool_name),input:e.tool_input,duration:0,blocked:m.hookSpecificOutput.permissionDecision==="deny",blockReason:m.hookSpecificOutput.permissionDecision==="deny"?_??"DEVFLOW_CONTEXT_REQUIRED":void 0},$=await r.sendEvent(T);$&&!T.blocked&&Bn(o,c,e.tool_name,e.tool_use_id,$,T.timestamp),$&&T.blocked&&await r.completeEvent({eventId:$,sessionId:c,error:_??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-T.timestamp,completedAt:Date.now()});try{let R=Ae(o),y={ts:i,tool:e.tool_name,sessionId:c,skill:u?.skillName??"(none)",requiredTools:u?.requiredMcpTools??[],isMcp:p,enforce:u?.executionId!==void 0,stateless:u?.executionId===void 0&&!p&&e.tool_name!=="Skill",bypassCount:R.bypassCount??0,decision:m.hookSpecificOutput.permissionDecision,env_CLAUDE_PLUGIN_ROOT:process.env.CLAUDE_PLUGIN_ROOT??"(unset)",cwd:process.cwd()};Te(Ce(o),`${JSON.stringify(y)}
|
|
4
|
-
`);}catch{}return
|
|
1
|
+
import {createHash as createHash$1}from'node:crypto';import {existsSync as existsSync$1,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync,rmSync,linkSync,renameSync,statSync}from'fs';import {join as join$1,dirname as dirname$1}from'path';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,projectClaudeToolName,resolveClaudeToolName,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {request}from'node:http';import {existsSync,mkdirSync as mkdirSync$1,appendFileSync,chmodSync,readFileSync as readFileSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1}from'node:fs';import {join,resolve,basename,relative,sep,dirname,isAbsolute,normalize}from'node:path';import {maybeRunDiagnosticLogCleanup,rotateDiagnosticLogFile,emitSemanticControlLog}from'@devflow-tools/telemetry';import {fileURLToPath}from'url';import {randomUUID,createHash}from'crypto';import {homedir}from'node:os';import {DatabaseSync}from'node:sqlite';function M(n,t,e){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:e,success:t.success!==!1,metadata:t});}finally{o.close();}}catch{}}var vt=getLocalApiKey(),K=join(getDevFlowStateRoot(),"errors");async function de(n,t,e={}){let o=e.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??bt();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let i=e.timeout??1500,r=e.durableMirror??true,s=e.maxRetries??(r?0:2),a=e.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await _t(o,n,t,i),a&®isterRuntimeHttpSuccess(o,n).transitioned&&M("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await Rt(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return ce(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,e.fallbackReason??(r?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(ce(n,l),M("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function bt(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function _t(n,t,e,o){return new Promise((i,r)=>{let s=JSON.stringify(e),a=new URL(t,n),c=false,l=u=>{c||(c=true,u?r(u):i());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":vt,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let p=u.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function ce(n,t){try{existsSync(K)||mkdirSync$1(K,{recursive:!0});let e=join(K,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${t.message}
|
|
2
|
+
`;rotateDiagnosticLogFile({path:e,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(e,o);}catch{}}function Rt(n){return new Promise(t=>setTimeout(t,n))}var ge=1e4,St=3e4,H=500,U=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=t?.database??null,this.ownsDatabase=!t?.database;let e=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(e)&&e>=0?e:100;}async sendEvent(t){let e={...t,input:this.truncateInput(t.input)};return this.commitOrCache("tool_call",e)?(this.postHttp("/api/telemetry/tool-call",e),t.eventId):null}async sendExecutionStart(t,e,o,i,r=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:t,sessionId:e,skillName:o,startedAt:i,projectRoot:r,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(t,e="completed",o=Date.now(),i){let r={executionId:t,status:e,finishedAt:o,metadata:i},s=this.commitOrCache("execution_complete",r);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",r),s}async sendSessionStart(t,e,o){let i={id:t,projectRoot:e,startedAt:o,label:e.split("/").pop()??"unknown"},r=this.commitOrCache("session_start",i);return r&&this.postHttp("/api/telemetry/sessions",i),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 o={sessionId:t,finishedAt:e},i=this.commitOrCache("session_end",o);return i&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(t)}/close`,{finishedAt:e})),i}async flushCache(){try{let e=this.getDatabase(),o=e.listTelemetryFailures({unresolvedOnly:!0,limit:H}).reverse();for(let i of o)try{this.applyOperation(i.operation,i.payload),e.resolveTelemetryFailure(i.id);}catch{}e.trimTelemetryFailures(H);}catch{}let t=(existsSync$1(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(e=>e.endsWith(".json")).map(e=>{let o=join$1(this.cacheDir,e);try{return {cacheFile:o,envelope:It(JSON.parse(readFileSync(o,"utf8")))}}catch{return null}}).filter(e=>e!==null).sort((e,o)=>e.envelope.timestamp-o.envelope.timestamp||me(e.envelope.operation)-me(o.envelope.operation));for(let{cacheFile:e,envelope:o}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:o.id,operation:o.operation,payload:o.payload,error:o.failure,createdAt:o.timestamp}),this.applyOperation(o.operation,o.payload),i.resolveTelemetryFailure(o.id),unlinkSync(e);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(t,e){try{return this.applyOperation(t,e),!0}catch(o){return this.cacheOperation(t,e,o),false}}applyOperation(t,e){let o=this.getDatabase();switch(t){case "tool_call":this.ensureParentSession(o,e),o.insertToolCallEvent(e);return;case "execution_start":this.ensureParentSession(o,e),o.insertSkillExecution({executionId:e.executionId,sessionId:e.sessionId,skillName:e.skillName,startedAt:e.startedAt,status:"running",requiredMcpTools:e.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(e.executionId,e.status,e.finishedAt,e.metadata);return;case "session_start":o.ensureSession(e),o.insertRun({id:he(e.id),source:"hook",tool:"session",input:{projectRoot:e.projectRoot},status:"active",startedAt:e.startedAt,tokenUsed:0,metadata:{sessionId:e.id,projectRoot:e.projectRoot}});return;case "complete_event":if(!o.updateToolCallEvent(e.eventId,{output:e.output===void 0?void 0:JSON.stringify(e.output),error:e.error,failureCategory:e.failureCategory,duration:e.duration}))throw new Error(`Tool call event ${e.eventId} is not available for completion`);return;case "session_end":o.closeSession(e.sessionId,e.finishedAt),o.updateRun(he(e.sessionId),{status:"completed",finishedAt:e.finishedAt});return}}ensureParentSession(t,e){let o=typeof e.sessionId=="string"?e.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let i=typeof e.projectRoot=="string"&&e.projectRoot.trim()?e.projectRoot:typeof e.input?.projectRoot=="string"&&e.input.projectRoot.trim()?e.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";t.ensureSession({id:o,projectRoot:i,label:i==="unknown"?void 0:i.split("/").pop(),startedAt:Number(e.startedAt??e.timestamp??Date.now())});}cacheOperation(t,e,o){let i=Date.now(),r={id:`failure:${i}:${Math.random().toString(36).slice(2,11)}`,operation:t,payload:e,failure:o instanceof Error?o.message:String(o),timestamp:i};try{let s=this.getDatabase();s.insertTelemetryFailure({id:r.id,operation:t,payload:e,error:r.failure,createdAt:i}),s.trimTelemetryFailures(H),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${i}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(r,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json")).sort();for(let e of t.slice(0,Math.max(0,t.length-H)))unlinkSync(join$1(this.cacheDir,e));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},St).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){de(t,e,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(t){let e=JSON.stringify(t);return e===void 0||e.length<=ge?t:{_truncated:true,_original_size:e.length,_preview:`${e.substring(0,ge)}...`}}};function me(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function he(n){return `hook-run:${n}`}function It(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.id!="string"||typeof t.operation!="string"||t.payload===void 0||typeof t.failure!="string"||typeof t.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return t}function F(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(n){return getProjectStateDir(F(n))}var h=emitSemanticControlLog;var Lt=2,jt=1;function $t(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname$1(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function ye(n=$t()){let t=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let e of t)try{if(!existsSync$1(e))continue;let o=JSON.parse(readFileSync(e,"utf8"));if(o.version!==Lt&&o.version!==jt||!Mt(o.commands)){h({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:"contract_mismatch",registryPath:e}});continue}return o.commands}catch(o){h({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:o.message,fallback:"next_registry_candidate"}});}return null}function Mt(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 q(e.mcpTools)&&q(e.blockedNative)&&(e.source===void 0||e.source==="core"||e.source==="plugin")&&(e.requiresContext===void 0||typeof e.requiresContext=="boolean")&&(e.runtimePackages===void 0||q(e.runtimePackages))&&(e.hostTools===void 0||Nt(e.hostTools))&&(e.evidenceMode===void 0||["static","runtime","mixed"].includes(e.evidenceMode))})}function Nt(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([t,e])=>t.length>0&&q(e))}function q(n){return Array.isArray(n)&&n.every(t=>typeof t=="string"&&t.length>0)}function ve(n){let t=ye();return t?t[n]?.mcpTools??[]:[]}function we(n){return Buffer.from(n,"utf8").toString("base64url")}function Jt(n,t,e){let o=t?.trim();if(o){let i=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${i}`}return `${n}:legacy-${e}-${randomUUID().slice(0,8)}`}function Ie(n){return `${n}:legacy-journal`}var I=class{constructor(t){this.projectRoot=t;this.sessions=new Map;this.sessionsDir=join$1(E(t),"hook-sessions");}registerSession(t){let e=t.trim();if(!e)throw new Error("session_id_required");let o=this.get(e);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let i=Date.now(),r={sessionId:e,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:i,lastActivityAt:i};return this.sessions.set(e,r),this.persist(r),r}startExecution(t,e,o){let i=this.registerSession(t);return (!i.executionId||i.skillName!==e)&&(i.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),i.skillName=e,i.requiredMcpTools=[...new Set(o)],delete i.contextInitialization,i.lastActivityAt=Date.now(),this.persist(i),i}beginContextInitialization(t,e){let o=this.registerSession(t);return o.contextInitialization={startedAt:Date.now(),...e?{toolUseId:e}:{}},o.lastActivityAt=Date.now(),this.persist(o),o}completeContextInitialization(t,e){let o=this.get(t);return o?(e&&o.contextInitialization?.toolUseId&&o.contextInitialization.toolUseId!==e||(delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o)),o):null}bindTaskIdentity(t,e){let o=this.registerSession(t);return o.activeTurnId=e.turnId,o.activeRequestId=e.requestId,o.intentArtifactHash=e.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(t){let e=t.trim();if(!e)return null;let o=this.sessions.get(e);if(o)return this.replayEvidenceJournal(o),o;let i=this.snapshotPath(e);if(!existsSync$1(i))return null;try{let r=JSON.parse(readFileSync(i,"utf8"));return r.sessionId!==e||r.projectRoot!==this.projectRoot?null:(r.requiredMcpTools=Array.isArray(r.requiredMcpTools)?r.requiredMcpTools:[],r.evidenceObligations=ke(r.evidenceObligations),r.evidenceDegradations=Ee(r.evidenceDegradations),r.evidenceOutcomes=De(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 o=structuredClone(e);return delete e.executionId,delete e.skillName,delete e.contextInitialization,e.requiredMcpTools=[],e.lastActivityAt=Date.now(),this.persist(e),o}addEvidenceObligation(t,e,o=Date.now(),i){let r=this.registerSession(t),a=(i?void 0:r.evidenceObligations.find(l=>l.contractId===e.id))?.obligationId??Jt(e.id,i,o);this.appendEvidenceEvent(t,{kind:"add",obligationId:a,contractId:e.id,at:o,contract:e},`add\0${a}`),this.replayEvidenceJournal(r);let c=r.evidenceObligations.find(l=>l.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,o,i,r=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(i)?i:"";if(!c)return null;this.appendEvidenceEvent(t,{kind:"correction",obligationId:e,contractId:a.contractId,at:r,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${e}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=r,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===e);return l?structuredClone(l):null}resolveEvidenceObligation(t,e){let o=this.get(t);if(!o)return false;let i=o.evidenceObligations.find(s=>s.obligationId===e);if(!i)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:i.contractId,at:r},`resolve\0${e}`),this.replayEvidenceJournal(o),o.lastActivityAt=r,this.persist(o),true}resolveDegradedEvidence(t,e){let o=this.get(t),i=o?.evidenceDegradations.find(s=>s.obligationId===e);if(!o||!i)return false;let r=Date.now();return this.appendEvidenceEvent(t,{kind:"resolve",obligationId:e,contractId:i.contractId,at:r},`resolve-degraded\0${e}\0${r}`),this.replayEvidenceJournal(o),o.lastActivityAt=r,this.persist(o),true}degradeEvidenceObligation(t,e,o,i=Date.now()){let r=this.get(t),s=r?.evidenceObligations.find(c=>c.obligationId===e);if(!r||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(t,{kind:"degrade",obligationId:e,contractId:s.contractId,at:i,reason:a},`degrade\0${e}\0${a}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}removeSession(t){let e=t.trim();e&&(this.sessions.delete(e),rmSync(this.snapshotPath(e),{force:true}),rmSync(this.evidenceJournalDir(e),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(t){return join$1(this.sessionsDir,`${we(t)}.json`)}evidenceJournalDir(t){return join$1(this.sessionsDir,"evidence-journal",we(t))}appendEvidenceEvent(t,e,o){let i=this.evidenceJournalDir(t);mkdirSync(i,{recursive:true,mode:448});let r=createHash("sha256").update(o).digest("hex"),s=join$1(i,`${e.kind}-${r}.json`);if(existsSync$1(s))return;let a=join$1(i,`.${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=ke(t.evidenceObligations),t.evidenceDegradations=Ee(t.evidenceDegradations),t.evidenceOutcomes=De(t.evidenceOutcomes);let e=this.evidenceJournalDir(t.sessionId);if(!existsSync$1(e))return;let o;try{o=readdirSync(e).filter(r=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(r)).slice(0,4096);}catch{return}let i=o.flatMap(r=>{try{let s=readFileSync(join$1(e,r),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Bt(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((r,s)=>r.at-s.at||xe(r.kind)-xe(s.kind));for(let r of i)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 o=t.evidenceOutcomes.find(s=>s.obligationId===e.obligationId);if(e.kind==="add"){if(o)return;let s=t.evidenceObligations.find(a=>a.obligationId===e.obligationId);s?(s.contract=e.contract,s.promptedAt=Math.min(s.promptedAt,e.at)):t.evidenceObligations.push({obligationId:e.obligationId,contractId:e.contractId,contract:e.contract,promptedAt:e.at,attempt:0,correctionRequested:false,violations:[]});return}let i=t.evidenceObligations.find(s=>s.obligationId===e.obligationId);if(e.kind==="correction"){if(!i||o||i.correctionFingerprint===e.fingerprint)return;i.attempt+=1,i.correctionRequested=true,i.correctionRequestedAt=e.at,i.correctionFingerprint=e.fingerprint,i.violations=e.violations;return}let r=i?.attempt??o?.attempt??0;if(e.kind==="resolve"&&o?.status==="degraded")t.evidenceOutcomes=t.evidenceOutcomes.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations=t.evidenceDegradations.filter(s=>s.obligationId!==e.obligationId);else if(o)return;e.kind==="degrade"?(t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceDegradations.push({obligationId:e.obligationId,contractId:e.contractId,reason:e.reason,degradedAt:e.at,attempt:r,contract:i?.contract})):t.evidenceObligations=t.evidenceObligations.filter(s=>s.obligationId!==e.obligationId),t.evidenceOutcomes.push({obligationId:e.obligationId,contractId:e.contractId,status:e.kind==="resolve"?"resolved":"degraded",completedAt:e.at,attempt:r,...e.kind==="degrade"?{reason:e.reason}:{}});}persist(t){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let e=this.snapshotPath(t.sessionId),o=`${e}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(t),{mode:384}),renameSync(o,e);}};function ke(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)||!Oe(e.contract))return [];let o=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:Ie(e.contractId),i=typeof e.correctionTranscriptHash=="string"?e.correctionTranscriptHash:void 0,r=e.correctionFingerprint??i;return r!==void 0&&!/^[a-f0-9]{64}$/.test(r)?[]:[{...e,obligationId:o,correctionFingerprint:r}]}).slice(-8):[]}function Ee(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 De(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 Bt(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 i={obligationId:typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:Ie(t.contractId),contractId:t.contractId,at:t.at};if(e==="add")return Oe(t.contract)?{kind:e,...i,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,...i,fingerprint:r,violations:t.violations}:null}return e==="resolve"?{kind:e,...i}:typeof t.reason=="string"&&t.reason.length<=240?{kind:e,...i,reason:t.reason}:null}function xe(n){return n==="add"?0:n==="correction"?1:2}function Oe(n){if(!n||typeof n!="object")return false;let t=n,e=t.requiredSections,o=t.prohibitedClaims;return t.version==="1.0"&&typeof t.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)&&typeof t.runtimeProfilingOccurred=="boolean"&&typeof t.samplingEvidenceOccurred=="boolean"&&Array.isArray(e)&&e.length===3&&e[0]==="\u5DE5\u5177\u53D1\u73B0"&&e[1]==="\u6A21\u578B\u5047\u8BBE"&&e[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(i=>typeof i=="string"&&i.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 B(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let t=n,e={};for(let o of ["lastMcpCall","bypassCount"])if(o in t){let i=t[o];if(i==null)continue;e[o]=typeof i=="number"&&Number.isFinite(i)&&i>=0?i:0;}return e}function Wt(n,t){return n.lastMcpCall===t.lastMcpCall&&n.bypassCount===t.bypassCount}function Ae(n,t,e){let o=e instanceof Error?e.message:String(e);h({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"enforcement_receipt",operation:t,reason:o,fallback:"fail_open"}});}function Ce(n,t,e){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let i={},r=o.updateHookReceipt(n,a=>(i=B(a),B(t(i)))),s=B(r);return {receipt:s,applied:!0,changed:!Wt(i,s)}}catch(i){return Ae(n,e,i),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function Te(n){let t;try{return t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),B(t.getHookReceipt(n))}catch(e){return Ae(n,"update",e),{}}finally{try{t?.close();}catch{}}}function Vt(n,t){return Ce(n,()=>t,"write").applied}function zt(n,t){return Ce(n,t,"update")}var Z={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"},Gt=new Set(["Write","Edit","NotebookEdit"]),Kt=new Set(["failed","timeout","unavailable"]);function Yt(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 W=class{constructor(t,e,o){this.projectRoot=t;this.sessionId=e;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let o=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(o&&o.expiresAt>Date.now())return "context_ready";o&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{t?.close();}catch{}}let e=new I(this.projectRoot).get(this.sessionId);return e?.executionId===this.executionId&&e.contextInitialization?"context_initializing":"context_gathering"}getContextReceipt(){if(!this.sessionId||!this.executionId)return null;let t;try{t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let e=t.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);return e&&e.expiresAt>Date.now()?e:(e&&t.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId),null)}catch{return null}finally{try{t?.close();}catch{}}}evaluate(t,e){let o=this.getPhase();if(e||t==="Skill")return {permissionDecision:"allow"};if(o==="context_initializing"&&Z[t])return {permissionDecision:"allow",additionalContext:`DevFlow context initialization is in progress; wait for ${projectClaudeToolName("get_project_context")} to complete before broad discovery with ${t}.`};if(o==="context_gathering"&&Z[t])return {permissionDecision:"allow",additionalContext:`DevFlow tip: call ${projectClaudeToolName("get_project_context")} first for scoped context instead of broad ${t} discovery.`};if(o==="context_ready"){if(Gt.has(t)){let c=this.evaluateRequiredAction();if(c)return c}return {permissionDecision:"allow"}}let i=Z[t];if(!i)return {permissionDecision:"allow"};let r=zt(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!r.applied)return {permissionDecision:"allow"};let s=r.receipt.bypassCount??0,a=Yt(t);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${t}\uFF0C\u5EFA\u8BAE\u7528 ${projectClaudeToolName(i)} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){Vt(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}recordDomainActionOutcome(t,e,o,i){if(!this.sessionId||!this.executionId)return false;let r;try{r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let s=r.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(!s||s.expiresAt<=Date.now()||s.canonicalAction?.tool!==t)return !1;let a=Date.now(),c=i?.trim()?`${i.trim()}:${e}`:`${t}:${e}:${a}`,l=s.actionAttempts??[];return r.upsertContextReceipt({...s,actionAttempts:l.some(d=>d.id===c||i&&d.toolUseId===i&&d.status===e)?l:[...l,{id:c,tool:t,status:e,attemptedAt:a,toolUseId:i,reason:o?.slice(0,500)}].slice(-20),actionSatisfiedAt:e==="succeeded"?a:s.actionSatisfiedAt,actionDegradation:e==="succeeded"?void 0:s.actionDegradation}),!0}catch{return false}finally{try{r?.close();}catch{}}}evaluateRequiredAction(){let t=this.getContextReceipt(),e=t?.canonicalAction;if(!t||!e||!e.required||e.status!=="required")return null;let o=e.binding;if(o.requiredContextReceipt!==t.contextHash||o.projectRoot!==this.projectRoot||o.sessionId!==this.sessionId||o.requestId!==t.requestId||o.executionId&&o.executionId!==this.executionId)return {permissionDecision:"deny",reasonCode:"DEVFLOW_ACTION_BINDING_STALE",reason:`DevFlow canonical action binding is stale or mismatched. Call ${projectClaudeToolName("get_project_context")} again before writing.`};if(t.actionSatisfiedAt)return null;if(t.actionDegradation?.authorizedByContextReceipt===t.contextHash)return {permissionDecision:"allow",additionalContext:`DevFlow degraded fallback authorized by context receipt ${t.contextHash}: ${t.actionDegradation.reason}`};let i=(t.actionAttempts??[]).filter(r=>r.tool===e.tool&&Kt.has(r.status));if(i.length>0){let r=i.at(-1),s={missedTool:e.tool,failedAttemptCount:i.length,reason:`${r.status}:${r.reason??"canonical domain action did not complete"}`,authorizedByContextReceipt:t.contextHash,authorizedAt:Date.now()};return this.persistDegradation(t,s),{permissionDecision:"allow",additionalContext:`DevFlow canonical tool ${projectClaudeToolName(e.tool)} ${r.status}; degraded direct write authorized by context receipt ${t.contextHash}. Preserve the action contract and verification plan.`}}return {permissionDecision:"deny",reasonCode:"DEVFLOW_REQUIRED_ACTION",reason:`DevFlow required action not completed. Call ${projectClaudeToolName(e.tool)} using context receipt ${t.contextHash}, then retry the write. Direct fallback is allowed only after unavailable, failed, or timeout evidence.`}}persistDegradation(t,e){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let i=o.getContextReceipt(t.projectRoot,t.sessionId,t.executionId);if(!i||i.contextHash!==t.contextHash||i.actionDegradation)return;o.upsertContextReceipt({...i,actionDegradation:e});let r=o.getSkillExecution(t.executionId);if(!r)return;let s=r.metadata&&typeof r.metadata=="object"?r.metadata:{},a=Array.isArray(s.requiredActionDegradations)?s.requiredActionDegradations:[];o.updateSkillExecution(t.executionId,{missedMcpTools:[...new Set([...r.missedMcpTools??[],e.missedTool])],failedToolCalls:Math.max(r.failedToolCalls??0,e.failedAttemptCount),fallbackCount:(r.fallbackCount??0)+1,fallbackReasons:[...new Set([...r.fallbackReasons??[],`required_action_${e.reason}`])],metadata:{...s,requiredActionDegradations:[...a,e]}});}catch{}finally{try{o?.close();}catch{}}}};var sn=10*1024*1024,an=5;function cn(n){return createHash$1("sha256").update(n).digest("hex").slice(0,16)}function Fe(n){return join(homedir(),".devflow","logs","hook-debug",`${cn(n)}.jsonl`)}function Pe(n,t,e={}){let o=e.maxBytes??sn,i=e.maxFiles??an;mkdirSync$1(dirname(n),{recursive:true,mode:448});let r=Buffer.byteLength(t);rotateDiagnosticLogFile({path:n,maxBytes:o,maxFiles:i,incomingBytes:r}),appendFileSync(n,t,{mode:384}),chmodSync(n,384);}var ee="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function Le(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}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 $e(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 fn=new Set(["Write","Edit","NotebookEdit"]),Me=`Claude native memory writes are disabled for this project. Use DevFlow explicit memory or ${projectClaudeToolName("memory_commit_turn")} so a canonical receipt is created.`;function Je(n){if(!fn.has(n.toolName))return null;let t=gn(n.toolInput);if(!t)return null;let e=mn(t,n.projectRoot),o=resolve(n.projectRoot,".claude");if(Ne(e,o)&&basename(e).toLocaleUpperCase("en-US")==="MEMORY.MD")return Me;let i=resolve(n.home??homedir(),".claude","projects");return Ne(e,i)&&relative(i,e).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?Me:null}function gn(n){for(let t of ["file_path","notebook_path","path"]){let e=n[t];if(typeof e=="string"&&e.trim())return e.trim()}return null}function mn(n,t){return resolve(isAbsolute(n)?n:resolve(t,n))}function Ne(n,t){let e=relative(t,n);return e===""||!e.startsWith(`..${sep}`)&&e!==".."&&!isAbsolute(e)}function ze(n){let t=kn(n.toolName,n.toolInput),e=t?En(n.projectRoot,n.toolName,n.toolInput):void 0;if(!t||!e||!n.toolUseId)return {allowed:true};let o=xn(e),i,r=0,s,a;try{a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100,readonly:!0});let l=a.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);i=l?.contextHash,r=l?.issuedAt??0,s=l?.canonicalAction?.binding.operationTargets?.find(d=>Sn(n.projectRoot,d.path,e));}catch{}finally{try{a?.close();}catch{}}let c={toolUseId:n.toolUseId,sessionId:n.sessionId,executionId:n.executionId,operation:t,path:e,before:o,contextReceipt:i,observedAt:Date.now()};if(An(n.projectRoot,c),t==="edit"||t==="write"||t==="delete"){let l=Cn(n.projectRoot,e),d=l?.success&&l.operation==="delete"&&!l.after.exists&&l.completedAt>=r,u=s?.expectedState==="existing"&&!o.exists||s?.expectedState==="missing"&&o.exists||!!(s?.contentHash&&o.hash!==s.contentHash);if(d||s?.expectedState==="existing"&&!o.exists)return Be(n,c,"DEVFLOW_FILE_STATE_DELETED","The target was deleted after the active Context receipt. Refresh project context before editing or recreating it.");if(u)return Be(n,c,"DEVFLOW_FILE_STATE_STALE","The target state no longer matches the active Context receipt. Refresh project context before overwriting it.")}return Ge(n,c,true),{allowed:true,pending:c}}function Be(n,t,e,o){return Ge(n,t,false,e),{allowed:false,reasonCode:e,reason:o,pending:t}}function Ge(n,t,e,o){h({event:"canonical.action.validated",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:n.executionId,contextReceipt:t.contextReceipt},level:e?"info":"warn",timestamp:Date.now(),data:{stage:"host_file_state_precondition",valid:e,operation:t.operation,targetPath:relative(n.projectRoot,t.path),targetExists:t.before.exists,targetHash:t.before.hash,reason:o,toolUseId:t.toolUseId}});}function kn(n,t){if(n==="Read")return "read";if(n==="Edit"||n==="NotebookEdit")return "edit";if(n==="Write")return "write";if(n==="Delete"||n==="Bash"&&Ke(t.command))return "delete"}function En(n,t,e){let o=Dn(e,["file_path","filePath","notebook_path","path","targetPath"])??(t==="Bash"?Ke(e.command):void 0);if(!o)return;let i=isAbsolute(o)?normalize(o):resolve(n,o),r=relative(n,i);return r.startsWith("..")||isAbsolute(r)?void 0:i}function Ke(n){return typeof n!="string"?void 0:/(?:^|[;&|]\s*)\s*(?:rm|unlink)\s+(?:-[A-Za-z]+\s+)*(?:--\s+)?(["']?)([^\s;&|"']+)\1/u.exec(n)?.[2]}function Dn(n,t){for(let e of t){let o=n[e];if(typeof o=="string"&&o.trim())return o.trim()}}function xn(n){if(!existsSync(n))return {exists:false};try{return {exists:!0,hash:createHash$1("sha256").update(readFileSync$1(n)).digest("hex")}}catch{return {exists:true}}}function Sn(n,t,e){return (isAbsolute(t)?normalize(t):resolve(n,t))===normalize(e)}function Ye(n){return join(E(n),"file-state")}function Qe(n){return join(Ye(n),"pending.json")}function In(n){return join(Ye(n),"observations.jsonl")}function On(n){try{return JSON.parse(readFileSync$1(Qe(n),"utf8"))}catch{return {}}}function An(n,t){let e=Qe(n);mkdirSync$1(dirname(e),{recursive:true});let o=On(n);o[t.toolUseId]=t,Tn(e,JSON.stringify(o));}function Cn(n,t){try{let e=readFileSync$1(In(n),"utf8").trim().split(`
|
|
3
|
+
`);for(let o=e.length-1;o>=0;o-=1){let i=JSON.parse(e[o]);if(i.path===t)return i}}catch{}}function Tn(n,t){let e=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync$1(e,t,{encoding:"utf8",mode:384}),renameSync$1(e,n);}var jn=new Set(["delivered","cancelled","rejected"]),$n=new Set(["cancelled","rejected"]),Mn=new Set(["Write","Edit","NotebookEdit","Bash"]);function Nn(n,t){if(n!=="Bash"||typeof t?.command!="string")return false;let e=t.command.trim(),i="git show [A-Za-z0-9._/:@{}^~+\\-]+(?: 2>/dev/null)?";return new RegExp(`^${i}(?: \\|\\| ${i})*$`,"u").test(e)?true:/[;&|<>`$()]|\\/u.test(e)?false:/^(?:ls|pwd|find|rg|grep|cat|sed|head|tail|wc)(?:\s|$)/u.test(e)||/^git\s+(?:show|status|diff|log|branch)(?:\s|$)/u.test(e)}function re(n,t,e,o,i){if(e.includes("delivery_rebind_session")||!Mn.has(e)||!t.trim()||Nn(e,i))return null;let r=join(n,".devflow","delivery-line","state.db");if(!existsSync(r))return null;let s;try{s=new DatabaseSync(r,{readOnly:!0,timeout:250});let a=s.prepare("SELECT id, payload, updated_at FROM delivery_cases").all(),c=new Set;if(!!s.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_workflow_bindings'").get()){let m=s.prepare("SELECT case_id, source_path, aliases FROM delivery_workflow_bindings WHERE status = 'enforced'").all();for(let f of m){let R=[];try{R=JSON.parse(f.aliases);}catch{}(f.source_path===n||R.includes(n))&&c.add(f.case_id);}}let d=[];for(let m of a){let f=JSON.parse(m.payload),R=c.has(m.id);(f.sessionId===t||t===m.id||R)&&d.push({id:m.id,payload:f,updatedAt:typeof m.updated_at=="number"?m.updated_at:typeof f.updatedAt=="number"?f.updatedAt:0});let y=typeof f.stage=="string"?f.stage:"unknown";if(!jn.has(y)){if(o&&y==="executing"){let g=s.prepare("SELECT id, lease_owner, fencing_token FROM delivery_tasks WHERE case_id = ? AND lease_expires_at > ? AND lease_owner IS NOT NULL AND fencing_token > 0 LIMIT 1").get(m.id,Date.now()),v=typeof f.sessionId=="string"?f.sessionId:void 0,L=typeof f.executionId=="string"?f.executionId:void 0,x=o===g?.id||o===g?.lease_owner||o===L,j=t===m.id||t===v;if(g?.id&&x&&j)return null}if(f.sessionId===t||t===m.id||R)return {code:"DELIVERY_AUTHORITY_REQUIRED",caseId:m.id,stage:y,message:`Delivery case ${m.id} is ${y}; use the Delivery task lease before modifying files.`}}}let u=d.sort((m,f)=>f.updatedAt-m.updatedAt)[0],p=typeof u?.payload.stage=="string"?u.payload.stage:void 0;return u&&p&&$n.has(p)?{code:"DELIVERY_AUTHORITY_REQUIRED",caseId:u.id,stage:p,message:`Delivery case ${u.id} is ${p}; start a new Delivery case or session before modifying files.`}:null}catch(a){return h({event:"hook.runtime.degraded",identity:{projectRoot:n},level:"warn",timestamp:Date.now(),data:{stage:"delivery_authority",operation:"delivery_write_block",reason:a instanceof Error?a.message:String(a),fallback:"fail_open_unverified_write"}}),null}finally{s?.close();}}function Xe(n=process.env){if(n.DEVFLOW_DISABLED==="1")return true;try{return existsSync(join(getDevFlowStateRoot({env:n}),"disable"))}catch{return false}}var Vn=250;function tt(n,t=process.env){let e=et(join(getDevFlowStateRoot({env:t}),"config.json")),o=et(join(n,".devflow","config.json")),i=se(t.DEVFLOW_HOOK_PROFILE)??se(o.profile)??se(e.profile)??"standard",r=Number(t.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??e.acknowledgementBudgetMs),s=Number.isSafeInteger(r)&&r>0?Math.min(r,5e3):Vn,a=new Set([...ae(e.disabledHandlers),...ae(o.disabledHandlers),...ae(t.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(zn).filter(c=>!!c));return {profile:i,acknowledgementBudgetMs:s,disabledHandlers:a}}function et(n){if(!existsSync(n))return {};try{let e=JSON.parse(readFileSync$1(n,"utf8")).hooks;return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return {}}}function se(n){return n==="minimal"||n==="standard"||n==="strict"||n==="advise"?n:void 0}function ae(n){return Array.isArray(n)?n.filter(t=>typeof t=="string"):[]}function zn(n){let t=n.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[t.replace(/-/g,"")]??t)||void 0}function nt(n){return n==="advise"}function ot(n){h({event:"hook.enforcement.shadow",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:"warn",timestamp:Date.now(),data:{tool:n.toolName,code:n.code??"DEVFLOW_POLICY",reason:n.reason.slice(0,500)}});try{process.stderr.write(`[devflow][shadow] would deny ${n.toolName}: ${n.reason}
|
|
4
|
+
`);}catch{}return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:`DevFlow shadow enforcement: this call would be denied under enforce mode (${n.code??"DEVFLOW_POLICY"}). Proceeding; the decision is recorded for graduation review.`}}}function C(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function z(n){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:n}}}function to(n){let t=E(n);return existsSync$1(t)||mkdirSync(t,{recursive:true}),t}function no(n,t,e,o,i,r){let s=join$1(to(n),"event-map.json"),a=[];try{existsSync$1(s)&&(a=JSON.parse(readFileSync(s,"utf-8")));}catch{}a.push({sessionId:t,toolName:e,toolUseId:o,eventId:i,timestamp:r}),a.length>1e3&&a.splice(0,a.length-1e3),writeFileSync(s,JSON.stringify(a));}function oo(n){switch(n){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function io(n,t,e){if(t!=="Read"||typeof e.file_path!="string"||!e.file_path.trim())return null;let o=e.file_path.startsWith("/")?e.file_path:join$1(n,e.file_path);try{if(statSync(o).isDirectory())return `Read accepts files, but "${e.file_path}" is a directory. Use Glob or Bash ls to inspect directory entries, then Read one file.`}catch{return null}return null}function ro(){let n=process.env.CLAUDE_PLUGIN_ROOT;if(!n)return null;let t=join$1(n,"package.json"),e=join$1(n,".mcp.json");try{let o=JSON.parse(readFileSync(t,"utf8")),r=JSON.parse(readFileSync(e,"utf8")).mcpServers?.devflow,s=r?.args;if(r?.command==="node"&&Array.isArray(s)&&s[0]==="${CLAUDE_PLUGIN_ROOT}/node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs")return existsSync$1(join$1(n,"node_modules/@devflow-tools/mcp-server/bin/devflow-mcp.cjs"))?null:"bundled DevFlow MCP runtime is not installed";let c=Array.isArray(s)?s.indexOf("--package"):-1,l=c>=0&&typeof s?.[c+1]=="string"?s[c+1]:void 0,d=typeof o.version=="string"?`@devflow-tools/mcp-server@${o.version}`:void 0;return l?d&&l!==d?`DevFlow MCP version mismatch (${l} vs ${d})`:null:"DevFlow MCP package configuration is missing"}catch{return "DevFlow MCP configuration could not be inspected"}}function so(){let n=process.env.CLAUDE_PLUGIN_ROOT?.trim();if(!n)return null;try{let t=join$1(n,"dist","runtime-manifest.json"),e=JSON.parse(readFileSync(t,"utf8")),o=typeof e.bundleHashes?.mcp=="string"?e.bundleHashes.mcp:void 0,i=join$1(n,"node_modules","@devflow-tools","mcp-server","dist","delivery-tools.js"),r=existsSync$1(i)?createHash$1("sha256").update(readFileSync(i)).digest("hex"):"missing";return !o||o!==r?"DevFlow runtime build does not match the active plugin manifest":null}catch{return "DevFlow runtime manifest is missing or invalid"}}function ao(n,t,e){return new Set(["Write","Edit","NotebookEdit"]).has(n)?true:n==="Bash"?!it(n,t):!!(e?.startsWith("delivery_")&&e!=="delivery_status")}function it(n,t){return n==="Grep"||n==="Glob"?true:n!=="Bash"||typeof t.command!="string"?false:/^(?:ls|pwd|find|rg|grep|git\s+(?:status|diff|log|branch)|cat|sed|head|tail|wc)\b/u.test(t.command.trim())}async function co(n){if(Xe())return C();let t=Le();try{if(!n||n.trim()==="")return C();let e=JSON.parse(n),o=Date.now();try{maybeRunDiagnosticLogCleanup(F(),{now:o});}catch{}let i=F(),r=new U,s=resolveClaudeToolName(e.tool_name,e.tool_input),a=s.status==="unsupported"?void 0:s.canonicalName;a&&(typeof e.tool_input.projectRoot!="string"||!e.tool_input.projectRoot.trim())&&(e.tool_input.projectRoot=i);let c=e.session_id?.trim();if(!c)return z(ee);let l=new I(i),d=l.get(c)!==null;if(l.registerSession(c),d||await r.sendSessionStart(c,i,Date.now()),e.tool_name==="Skill"){let b=e.tool_input?.skill,_=b?je(b):null;if(_){let k=l.get(c)?.executionId,w=l.startExecution(c,_,ve(_));w.executionId&&w.executionId!==k&&await r.sendExecutionStart(w.executionId,c,_,w.lastActivityAt,i,w.requiredMcpTools);}}let u=l.get(c);a==="get_project_context"&&l.beginContextInitialization(c,e.tool_use_id),a&&(e.tool_input._devflow_session_id=c,e.tool_input._devflow_execution_id=u?.executionId??c,u?.activeTurnId&&(e.tool_input._devflow_turn_id=u.activeTurnId),u?.activeRequestId&&(e.tool_input._devflow_request_id=u.activeRequestId),u?.intentArtifactHash&&(e.tool_input._devflow_intent_artifact_hash=u.intentArtifactHash),u?.skillName&&(e.tool_input._devflow_active_skill=u.skillName),e.tool_use_id&&(e.tool_input._devflow_tool_use_id=e.tool_use_id));let p=e.tool_name.startsWith("mcp__"),m=a,f=l.get(c),R=new W(i,c,f?.executionId),y=R.getPhase(),g,v,L=io(i,e.tool_name,e.tool_input),x=re(i,c,e.tool_name,f?.executionId,e.tool_input),j=!x&&ao(e.tool_name,e.tool_input,m)?so():null;if(j)g=z(`DevFlow runtime build mismatch: ${j}. Refresh the plugin installation before relying on delivery_* results; file edits remain allowed.`);else if(L)v="DEVFLOW_DIRECTORY_READ_INVALID",g={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:L}};else if(x)v=x.code,g={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:`${x.message} Resolve the case blocker or obtain an authorized task lease before retrying.`}};else {let b=Je({toolName:e.tool_name,toolInput:e.tool_input,projectRoot:i}),_=ze({projectRoot:i,sessionId:c,executionId:f?.executionId,toolUseId:e.tool_use_id,toolName:e.tool_name,toolInput:e.tool_input}),k=b?{permissionDecision:"deny",reason:b}:_.allowed?R.evaluate(e.tool_name,p):{permissionDecision:"deny",reason:_.reason,reasonCode:_.reasonCode},w=!p&&it(e.tool_name,e.tool_input)&&(y==="context_gathering"||y==="context_initializing")?ro():null;w?(g=z(`DevFlow MCP is unavailable or stale: ${w}. This read-only fallback is temporary; refresh the plugin installation and call ${projectClaudeToolName("get_project_context")} before editing.`),v=void 0):k.permissionDecision==="deny"?(v=b?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":k.reasonCode??"DEVFLOW_CONTEXT_REQUIRED",g={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:k.reason??"MCP context required"}}):k.additionalContext?g=z(k.additionalContext):g=C();}if(g.hookSpecificOutput.permissionDecision==="deny"&&nt(tt(i).profile)){let b=g.hookSpecificOutput.permissionDecisionReason??"policy deny";g=ot({projectRoot:i,sessionId:c,toolName:e.tool_name,code:v,reason:b}),v=void 0;}a&&(g.hookSpecificOutput.updatedInput=e.tool_input),t&&g.hookSpecificOutput.permissionDecision==="allow"&&(g.hookSpecificOutput.additionalContext=ee);let rt=f?.executionId??c,T={eventId:$e(c,e.tool_use_id),executionId:rt,sessionId:c,projectRoot:i,toolUseId:e.tool_use_id,timestamp:Date.now(),toolName:e.tool_name,toolType:p?"mcp":e.tool_name==="Agent"?"subagent":"direct",isMcpTool:p,mcpToolName:m,mcpEnforced:p&&(y==="context_gathering"||y==="context_initializing"),mcpFallback:!p&&(y==="context_gathering"||y==="context_initializing"),kind:oo(e.tool_name),input:e.tool_input,duration:0,blocked:g.hookSpecificOutput.permissionDecision==="deny",blockReason:g.hookSpecificOutput.permissionDecision==="deny"?v??"DEVFLOW_CONTEXT_REQUIRED":void 0},$=await r.sendEvent(T);$&&!T.blocked&&no(i,c,e.tool_name,e.tool_use_id,$,T.timestamp),$&&T.blocked&&await r.completeEvent({eventId:$,sessionId:c,error:v??"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-T.timestamp,completedAt:Date.now()});try{let b=Te(i),_={ts:o,tool:e.tool_name,sessionId:c,skill:u?.skillName??"(none)",requiredTools:u?.requiredMcpTools??[],isMcp:p,enforce:u?.executionId!==void 0,stateless:u?.executionId===void 0&&!p&&e.tool_name!=="Skill",bypassCount:b.bypassCount??0,decision:g.hookSpecificOutput.permissionDecision,env_CLAUDE_PLUGIN_ROOT:process.env.CLAUDE_PLUGIN_ROOT??"(unset)",cwd:process.cwd()};Pe(Fe(i),`${JSON.stringify(_)}
|
|
5
|
+
`);}catch{}return g}catch{try{let e=JSON.parse(n),o=F(),i=re(o,String(e.session_id??""),String(e.tool_name??""),void 0,e.tool_input);if(i)return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:i.message}}}catch{}return C()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-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 co(t);n(JSON.stringify(e));}),process.stdin.on("error",()=>{n(JSON.stringify(C())),process.exit(0);}),setTimeout(()=>{n(JSON.stringify(C())),process.exit(0);},4e3).unref();}export{co as handlePreToolUse};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifestVersion": "devflow-runtime.v1",
|
|
3
|
-
"packageVersion": "0.
|
|
4
|
-
"sourceCommit": "
|
|
3
|
+
"packageVersion": "0.19.2",
|
|
4
|
+
"sourceCommit": "3b0b20607162ab93415b204c0bfb46c15df328b2",
|
|
5
5
|
"bundleHashes": {
|
|
6
|
-
"hooks": "
|
|
6
|
+
"hooks": "40df4bca4427aee4f71c5ca021b96ba5d22951b1677162cd4d1e15625b343563",
|
|
7
7
|
"mcp": "ae638ba33e7807efad1554deadd8517002e7e6a263a4f4745ff7cb2081671997",
|
|
8
|
-
"cli": "
|
|
8
|
+
"cli": "6107445bfaec2e9a72d6cbf165f7dbdd1077388d8d0d6d5f883571e90d791871"
|
|
9
9
|
},
|
|
10
|
-
"registryHash": "
|
|
10
|
+
"registryHash": "78f76b635d89d57196a3783acfe10755aa3bbb217f5e3eb196537213e02086e4",
|
|
11
11
|
"stateDbPath": "<projectRoot>/.devflow/delivery-line/state.db",
|
|
12
|
-
"builtAt":
|
|
13
|
-
"manifestHash": "
|
|
12
|
+
"builtAt": 1793613940630,
|
|
13
|
+
"manifestHash": "86396308b48b6f341c18d9b7b3beaaaa43eb42a83724f6388616a073b8f5c503"
|
|
14
14
|
}
|
package/hooks/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# DevFlow Hooks 注册表
|
|
2
|
+
|
|
3
|
+
`hooks.json` 中每个条目的用途说明。Claude Code 的 hooks schema 只接受 `matcher` 与 `hooks` 键,
|
|
4
|
+
`id` / `description` 元数据存放于此,不写入 `hooks.json`(否则 CLI 启动时会产生 unknown keys 警告)。
|
|
5
|
+
|
|
6
|
+
| id | 事件 | 脚本 | 说明 |
|
|
7
|
+
| --- | --- | --- | --- |
|
|
8
|
+
| `session:start:banner` | SessionStart | `session-start` | Compact DevFlow session banner: capability pointer, memory snapshot, gateway status |
|
|
9
|
+
| `pre:devflow-gate` | PreToolUse | `pre-tool-use` | Delivery write gate + execution/context-receipt tracking for Skill and MCP calls. Read-only discovery tools (Read/Grep/Glob/Agent/WebSearch) are deliberately NOT matched — they are advisory only. |
|
|
10
|
+
| `post:telemetry` | PostToolUse | `post-tool-use` | Telemetry completion + memory turn staging (non-blocking observation) |
|
|
11
|
+
| `post:failure-learning` | PostToolUseFailure | `post-tool-use-failure` | Failure classification + learning extraction from failed tool calls |
|
|
12
|
+
| `prompt:intent` | UserPromptSubmit | `user-prompt-submit` | Task intent capture + turn correlation |
|
|
13
|
+
| `stop:finalize` | Stop | `stop` | Memory turn finalize + graceful daemon shutdown |
|
|
14
|
+
| `compact:persist` | PreCompact | `pre-compact` | Persist durable state before context compaction |
|
|
15
|
+
| `session:end:cleanup` | SessionEnd | `session-end` | Lifecycle cleanup: release delivery leases, spool finalize, state cleanup |
|
package/hooks/hooks.json
CHANGED
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start\"",
|
|
10
10
|
"timeout": 15
|
|
11
11
|
}
|
|
12
|
-
]
|
|
13
|
-
"description": "Compact DevFlow session banner: capability pointer, memory snapshot, gateway status",
|
|
14
|
-
"id": "session:start:banner"
|
|
12
|
+
]
|
|
15
13
|
}
|
|
16
14
|
],
|
|
17
15
|
"PreToolUse": [
|
|
@@ -23,9 +21,7 @@
|
|
|
23
21
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-tool-use\"",
|
|
24
22
|
"timeout": 10
|
|
25
23
|
}
|
|
26
|
-
]
|
|
27
|
-
"description": "Delivery write gate + execution/context-receipt tracking for Skill and MCP calls. Read-only discovery tools (Read/Grep/Glob/Agent/WebSearch) are deliberately NOT matched — they are advisory only.",
|
|
28
|
-
"id": "pre:devflow-gate"
|
|
24
|
+
]
|
|
29
25
|
}
|
|
30
26
|
],
|
|
31
27
|
"PostToolUse": [
|
|
@@ -37,9 +33,7 @@
|
|
|
37
33
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use\"",
|
|
38
34
|
"timeout": 10
|
|
39
35
|
}
|
|
40
|
-
]
|
|
41
|
-
"description": "Telemetry completion + memory turn staging (non-blocking observation)",
|
|
42
|
-
"id": "post:telemetry"
|
|
36
|
+
]
|
|
43
37
|
}
|
|
44
38
|
],
|
|
45
39
|
"PostToolUseFailure": [
|
|
@@ -51,9 +45,7 @@
|
|
|
51
45
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use-failure\"",
|
|
52
46
|
"timeout": 10
|
|
53
47
|
}
|
|
54
|
-
]
|
|
55
|
-
"description": "Failure classification + learning extraction from failed tool calls",
|
|
56
|
-
"id": "post:failure-learning"
|
|
48
|
+
]
|
|
57
49
|
}
|
|
58
50
|
],
|
|
59
51
|
"UserPromptSubmit": [
|
|
@@ -65,9 +57,7 @@
|
|
|
65
57
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/user-prompt-submit\"",
|
|
66
58
|
"timeout": 5
|
|
67
59
|
}
|
|
68
|
-
]
|
|
69
|
-
"description": "Task intent capture + turn correlation",
|
|
70
|
-
"id": "prompt:intent"
|
|
60
|
+
]
|
|
71
61
|
}
|
|
72
62
|
],
|
|
73
63
|
"Stop": [
|
|
@@ -79,9 +69,7 @@
|
|
|
79
69
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop\"",
|
|
80
70
|
"timeout": 15
|
|
81
71
|
}
|
|
82
|
-
]
|
|
83
|
-
"description": "Memory turn finalize + graceful daemon shutdown",
|
|
84
|
-
"id": "stop:finalize"
|
|
72
|
+
]
|
|
85
73
|
}
|
|
86
74
|
],
|
|
87
75
|
"PreCompact": [
|
|
@@ -93,9 +81,7 @@
|
|
|
93
81
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-compact\"",
|
|
94
82
|
"timeout": 15
|
|
95
83
|
}
|
|
96
|
-
]
|
|
97
|
-
"description": "Persist durable state before context compaction",
|
|
98
|
-
"id": "compact:persist"
|
|
84
|
+
]
|
|
99
85
|
}
|
|
100
86
|
],
|
|
101
87
|
"SessionEnd": [
|
|
@@ -107,9 +93,7 @@
|
|
|
107
93
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-end\"",
|
|
108
94
|
"timeout": 15
|
|
109
95
|
}
|
|
110
|
-
]
|
|
111
|
-
"description": "Lifecycle cleanup: release delivery leases, spool finalize, state cleanup",
|
|
112
|
-
"id": "session:end:cleanup"
|
|
96
|
+
]
|
|
113
97
|
}
|
|
114
98
|
]
|
|
115
99
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.2",
|
|
4
4
|
"description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.19.
|
|
16
|
-
"@devflow-tools/context-engine": "0.19.
|
|
17
|
-
"@devflow-tools/database": "0.19.
|
|
18
|
-
"@devflow-tools/mcp-server": "0.19.
|
|
19
|
-
"@devflow-tools/memory-engine": "0.19.
|
|
20
|
-
"@devflow-tools/sdk": "0.19.
|
|
21
|
-
"@devflow-tools/semantic-engine": "0.19.
|
|
22
|
-
"@devflow-tools/server": "0.19.
|
|
23
|
-
"@devflow-tools/task-runtime": "0.19.
|
|
24
|
-
"@devflow-tools/telemetry": "0.19.
|
|
25
|
-
"@devflow-tools/workflow-engine": "0.19.
|
|
15
|
+
"@devflow-tools/benchmark": "0.19.2",
|
|
16
|
+
"@devflow-tools/context-engine": "0.19.2",
|
|
17
|
+
"@devflow-tools/database": "0.19.2",
|
|
18
|
+
"@devflow-tools/mcp-server": "0.19.2",
|
|
19
|
+
"@devflow-tools/memory-engine": "0.19.2",
|
|
20
|
+
"@devflow-tools/sdk": "0.19.2",
|
|
21
|
+
"@devflow-tools/semantic-engine": "0.19.2",
|
|
22
|
+
"@devflow-tools/server": "0.19.2",
|
|
23
|
+
"@devflow-tools/task-runtime": "0.19.2",
|
|
24
|
+
"@devflow-tools/telemetry": "0.19.2",
|
|
25
|
+
"@devflow-tools/workflow-engine": "0.19.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@devflow-tools/devflow": "0.
|
|
28
|
+
"@devflow-tools/devflow": "0.19.2"
|
|
29
29
|
},
|
|
30
30
|
"allowScripts": {
|
|
31
31
|
"better-sqlite3@12.11.1": true,
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"hooks",
|
|
51
51
|
"skills"
|
|
52
52
|
],
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "3b0b20607162ab93415b204c0bfb46c15df328b2",
|
|
54
54
|
"license": "MIT",
|
|
55
55
|
"repository": {
|
|
56
56
|
"type": "git",
|