@devflow-tools/cli 0.18.13 → 0.18.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +6 -6
- package/dist/plugin-files/dist/hooks/hook-daemon.js +28 -28
- package/dist/plugin-files/dist/hooks/post-tool-use-failure.js +2 -2
- package/dist/plugin-files/dist/hooks/post-tool-use.js +5 -5
- package/dist/plugin-files/dist/hooks/pre-tool-use.js +4 -4
- package/dist/plugin-files/dist/hooks/session-end.js +5 -5
- package/dist/plugin-files/dist/hooks/stop.js +2 -2
- package/dist/plugin-files/dist/hooks/user-prompt-submit.js +4 -4
- package/dist/plugin-files/dist/skills/devflow:delivery/SKILL.md +3 -0
- package/dist/plugin-files/package.json +13 -13
- package/dist/plugin-files/skills/delivery/SKILL.md +3 -0
- package/package.json +28 -28
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {getLocalApiKey,getDevFlowStateRoot,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {existsSync,mkdirSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {DatabaseSync}from'node:sqlite';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function z(n){return Buffer.from(n,"utf8").toString("base64url")}function Se(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}bindTaskIdentity(e,t){let o=this.registerSession(e);return o.activeTurnId=t.turnId,o.activeRequestId=t.requestId,o.intentArtifactHash=t.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync$1(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Se(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(e,t){let o=this.get(e),r=o?.evidenceDegradations.find(s=>s.obligationId===t);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${z(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",z(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync$1(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Re(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??o?.attempt??0;if(t.kind==="resolve"&&o?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(o)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:r?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!Y(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Re(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let r={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return Y(e.contract)?{kind:t,...r,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...r,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...r}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...r,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function Y(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Fe=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Ne();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await Le(o,n,e,r),a&®isterRuntimeHttpSuccess(o,n).transitioned&&T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){l=m instanceof Error?m:new Error(String(m)),u<s&&await qe(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(X(n,l),T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function Ne(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function Le(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=u=>{c||(c=true,u?i(u):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Fe,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let m=u.statusCode??0;l(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function X(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${e.message}
|
|
1
|
+
import {getLocalApiKey,getDevFlowStateRoot,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {existsSync,mkdirSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {DatabaseSync}from'node:sqlite';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function U(n){return Buffer.from(n,"utf8").toString("base64url")}function Se(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r),r}beginContextInitialization(e,t){let o=this.registerSession(e);return o.contextInitialization={startedAt:Date.now(),...t?{toolUseId:t}:{}},o.lastActivityAt=Date.now(),this.persist(o),o}completeContextInitialization(e,t){let o=this.get(e);return o?(t&&o.contextInitialization?.toolUseId&&o.contextInitialization.toolUseId!==t||(delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o)),o):null}bindTaskIdentity(e,t){let o=this.registerSession(e);return o.activeTurnId=t.turnId,o.activeRequestId=t.requestId,o.intentArtifactHash=t.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync$1(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,delete t.contextInitialization,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Se(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(e,t){let o=this.get(e),r=o?.evidenceDegradations.find(s=>s.obligationId===t);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${U(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",U(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync$1(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Re(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??o?.attempt??0;if(t.kind==="resolve"&&o?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(o)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:r?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!Y(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Re(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let r={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return Y(e.contract)?{kind:t,...r,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...r,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...r}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...r,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function Y(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Fe=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Ne();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await Le(o,n,e,r),a&®isterRuntimeHttpSuccess(o,n).transitioned&&T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){l=m instanceof Error?m:new Error(String(m)),u<s&&await qe(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(X(n,l),T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function Ne(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function Le(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=u=>{c||(c=true,u?i(u):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Fe,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let m=u.statusCode??0;l(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function X(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${e.message}
|
|
2
2
|
`;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(t,o);}catch{}}function qe(n){return new Promise(e=>setTimeout(e,n))}function te(n,e){let t=Je(n);mkdirSync(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function Je(n){return join(w(n),"session-finalize-pending")}var p=emitSemanticControlLog;function M(n){let{projectRoot:e,...t}=n;try{return new O(e).dispatchBoundary(t).snapshot??null}catch(o){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:o instanceof Error?o.message:String(o),tool:n.producer}}),null}}var O=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=Xe(e.kind,e.payload??{});if(!t)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=Ye(o,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${r.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function Ye(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,o=e.turnId??t?.canonicalAction?.binding.turnId,r=e.requestId??t?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function Xe(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var ot=512*1024,rt=500;var it=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ie(n){let e=n.runtimeStore??new I(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return st(n,e),null;let o=$(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=se(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId),x(n,s,"satisfied",r);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a}),x(n,s,"correction_requested",r,a);continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved"),x(n,s,"degraded",r,a);}return i.length===0?null:at(i)}function st(n,e){let t=(e.get(n.sessionId)?.evidenceDegradations??[]).filter(i=>i.contract).slice(-8);if(t.length===0)return;let o=t.map(i=>({obligationId:i.obligationId,contractId:i.contractId,contract:i.contract,promptedAt:i.degradedAt,attempt:i.attempt,correctionRequested:true,violations:[]})),r=$(n.transcriptPath,o);if(!(!r.answer||!r.fingerprint))for(let i of o)se(r.answer,[i]).length>0||e.resolveDegradedEvidence(n.sessionId,i.obligationId)&&x(n,i,"satisfied",r.fingerprint);}function x(n,e,t,o,r=[]){t!=="correction_requested"&&M({projectRoot:n.projectRoot,sessionId:n.sessionId,kind:t==="satisfied"?"verification.succeeded":"verification.failed",payload:{receiptId:e.obligationId,reasonCode:t==="satisfied"?"performance_evidence_satisfied":"performance_evidence_unresolved"},dedupeKey:`${e.obligationId}:${t}:${e.attempt}`,producer:"devflow-evidence-contract"}),p({event:"verification.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:t==="satisfied"?"info":t==="degraded"?"error":"warn",timestamp:Date.now(),data:{stage:"performance_evidence_transition",status:t,contractId:e.contractId,obligationId:e.obligationId,attempt:e.attempt,answerFingerprint:o,violations:r,supersedesDegradation:t==="satisfied"&&e.attempt>0}});}function at(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
|
|
3
3
|
|
|
4
4
|
---
|
|
@@ -7,7 +7,7 @@ import {getLocalApiKey,getDevFlowStateRoot,acquireRuntimeHttpCircuit,registerRun
|
|
|
7
7
|
|
|
8
8
|
`)}}function se(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=ae(n.split(/\r?\n/)),i=ce(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let l=r.claimLines[c].trim();if(!l||dt(l))continue;let d=i.byLine.get(c);for(let u of ft(l))ut(u,d,a,t);}return [...t]}function ae(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>ct(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function ct(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function dt(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?lt(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function lt(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function ut(n,e,t,o){let r=/\bP0\b/gi;for(let y of n.matchAll(r))re(n,y.index??0,y[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))re(n,y.index??0,y[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))pt(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&o.add("unsupported_benefit_percentage"),d&&!u&&o.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),g=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&h&&!g&&!t&&o.add("raf_without_sampling_evidence");}function re(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=mt(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function mt(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function pt(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function ft(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function $(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,ot),s=Buffer.alloc(i),a=0;for(;a<i;){let g=readSync(t,s,a,i-a,r.size-i+a);if(g===0)break;a+=g;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
|
|
9
9
|
`)+1)));let l=c.split(/\r?\n/).slice(-rt),d=e.length>0?Math.min(...e.map(g=>g.promptedAt)):0,u=yt(l,d),h=[...u].reverse().find(g=>gt(g.text,e))??u.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function gt(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=ce(ae(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function P(n){return $(n,[]).answer}function yt(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=ht(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,d=typeof l=="string"?l:Array.isArray(l)?l.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
|
|
10
|
-
`):"";if(d.trim()){let u=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(u).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:g});}}catch{continue}}return t}function ht(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=it.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}var bt={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function F(n){return _t(n)}function _t(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=kt(e,n.artifact);if(xt(t.toState))return t;let o=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return t;let s=o?wt(n.artifact,o):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?St(n.artifact,o):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function wt(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function St(n,e){let t=e.canonicalAction,r=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||Rt(n)?"action_required":"action_not_required"}function Rt(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function kt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,o,r){if(!bt[e.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${o}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:o,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:r,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:o,receiptId:s,reason:r}}),a}function xt(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n,e){let t=join(n,".devflow","delivery-line","state.db");if(!existsSync(t)||!e.trim())return 0;let o;try{o=new DatabaseSync(t,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(e,e),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let l=JSON.parse(a.payload);c=l.evidence?.some(d=>d.metadata?.trust==="external-untrusted")?"untrusted":l.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let l=`session.closed:${a.id}:${e}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(l,a.id,l,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:e,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function le(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Ot(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function Mt(n,e=_(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o};try{de(e,s);}catch{}let l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=l.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!r)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Ot(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=Mt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var E=1,qt="memory-snapshot-v1.json",Ht=512*1024,fe=256*1024,ge=2e3,Ut=500,zt=10,Bt=240,Jt=300*1e3,Wt=720*60*60*1e3,Gt=2147483647;function Kt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Vt(n,e={}){let t=S(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(o,qt)}function Yt(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function L(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Xt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&L(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ye(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=b(e),i=S(r),s=o.generation===void 0?0:o.generation;return o.version!==E||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>fe||!L(o.memoryIds,ge)||!Array.isArray(o.conflicts)||o.conflicts.length>Ut||!o.conflicts.every(Xt)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Jt||!Number.isInteger(s)||s<0||s>Gt||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Zt(o.degradation)?null:{...o,generation:s}}function Qt(n,e,t,o,r=0){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function en(n,e={}){let t=e.now??Date.now(),o=Vt(n,e),r;try{r=openSync(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(r);if(!i.isFile()||i.size<=0||i.size>Ht)throw new Error("cache_size_invalid");let s=Kt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(r,"utf8")),c=ye(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Wt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Qt(n,a?"pending":"degraded",a?"cache_missing":Yt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync(r);}catch{}}}function tn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function nn(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=ye(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=fe){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:o.markdown,memoryIds:L(o.memoryIds,ge)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function N(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Bt).join("")}function on(n){if(n.length===0)return "";let e=n.slice(0,zt),t=e.map(o=>{let r=N(o.family,"unknown"),i=N(o.entity,"unknown"),s=N(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
10
|
+
`):"";if(d.trim()){let u=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(u).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:g});}}catch{continue}}return t}function ht(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=it.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}var bt={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function F(n){return _t(n)}function _t(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=kt(e,n.artifact);if(xt(t.toState))return t;let o=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return t;let s=o?wt(n.artifact,o):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?St(n.artifact,o):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function wt(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function St(n,e){let t=e.canonicalAction,r=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||Rt(n)?"action_required":"action_not_required"}function Rt(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function kt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,o,r){if(!bt[e.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${o}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:o,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:r,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:o,receiptId:s,reason:r}}),a}function xt(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n,e){let t=join(n,".devflow","delivery-line","state.db");if(!existsSync(t)||!e.trim())return 0;let o;try{o=new DatabaseSync(t,{timeout:250});let r=o.prepare("SELECT id, payload FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(e,e),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r){let c="incomplete";try{let l=JSON.parse(a.payload);c=l.evidence?.some(d=>d.metadata?.trust==="external-untrusted")?"untrusted":l.stage==="delivered"?"clean":"incomplete";}catch{}if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let l=`session.closed:${a.id}:${e}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(l,a.id,l,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:e,releasedLeases:i,outcome:c}),Date.now());}}return i}catch{return 0}finally{o?.close();}}function le(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Ot(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function Mt(n,e=_(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o};try{de(e,s);}catch{}let l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=l.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...u?.id?{workItemId:u.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!r)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Ot(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=Mt(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var E=1,qt="memory-snapshot-v1.json",Ht=512*1024,fe=256*1024,ge=2e3,zt=500,Ut=10,Bt=240,Jt=300*1e3,Wt=720*60*60*1e3,Gt=2147483647;function Kt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Vt(n,e={}){let t=S(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(o,qt)}function Yt(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function L(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Xt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&L(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ye(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=b(e),i=S(r),s=o.generation===void 0?0:o.generation;return o.version!==E||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>fe||!L(o.memoryIds,ge)||!Array.isArray(o.conflicts)||o.conflicts.length>zt||!o.conflicts.every(Xt)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Jt||!Number.isInteger(s)||s<0||s>Gt||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Zt(o.degradation)?null:{...o,generation:s}}function Qt(n,e,t,o,r=0){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function en(n,e={}){let t=e.now??Date.now(),o=Vt(n,e),r;try{r=openSync(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(r);if(!i.isFile()||i.size<=0||i.size>Ht)throw new Error("cache_size_invalid");let s=Kt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(r,"utf8")),c=ye(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Wt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Qt(n,a?"pending":"degraded",a?"cache_missing":Yt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync(r);}catch{}}}function tn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function nn(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=ye(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=fe){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:o.markdown,memoryIds:L(o.memoryIds,ge)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function N(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Bt).join("")}function on(n){if(n.length===0)return "";let e=n.slice(0,Ut),t=e.map(o=>{let r=N(o.family,"unknown"),i=N(o.entity,"unknown"),s=N(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
11
11
|
${t.join(`
|
|
12
12
|
`)}`}function rn(n){let e=n.now??Date.now();if(tn(n.configPath)===false)return "";let t=nn(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:en(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
|
|
13
13
|
DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=on(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,resolveProjectCapabilityProfile,resolveCapabilityRollout,claudeCodeRuntimeAdapter,semanticTextHash,stableRuntimeHash,resolveRuntimeActivationSnapshot,getProjectStateDir,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,readRuntimeState}from'@devflow-tools/sdk';import {existsSync,readFileSync as readFileSync$1,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {randomUUID,createHash}from'crypto';import {fileURLToPath}from'url';import {emitSemanticControlLog,SemanticRuntimeEventProjector,rotateDiagnosticLogFile}from'@devflow-tools/telemetry';import {readFileSync,openSync,constants,fstatSync,closeSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1,realpathSync,existsSync as existsSync$1,appendFileSync}from'node:fs';import {join,resolve,relative}from'node:path';import {request}from'node:http';import {createHash as createHash$1,randomUUID as randomUUID$1}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';function h(n,e,t){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var K="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function B(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Je(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(n){return getProjectStateDir(Je(n))}function X(n){return Buffer.from(n,"utf8").toString("base64url")}function Be(n,e,t){let r=e?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function re(n){return `${n}:legacy-journal`}var x=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(k(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=t,o.requiredMcpTools=[...new Set(r)],o.lastActivityAt=Date.now(),this.persist(o),o}bindTaskIdentity(e,t){let r=this.registerSession(e);return r.activeTurnId=t.turnId,r.activeRequestId=t.requestId,r.intentArtifactHash=t.intentArtifactHash,r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let r=this.sessions.get(t);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(t);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=Z(i.evidenceObligations),i.evidenceDegradations=Q(i.evidenceDegradations),i.evidenceOutcomes=ee(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let r=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),r}addEvidenceObligation(e,t,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(m=>m.contractId===t.id))?.obligationId??Be(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:r,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let d=i.evidenceObligations.find(m=>m.obligationId===a);return d?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(d)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,r,o,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(l=>l.obligationId===t);if(!s||!a)return null;let d=/^[a-f0-9]{64}$/.test(o)?o:"";if(!d)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:d,violations:r.slice(0,16).map(l=>l.slice(0,240))},`correction\0${t}\0${d}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let m=s.evidenceObligations.find(l=>l.obligationId===t);return m?structuredClone(m):null}resolveEvidenceObligation(e,t){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===t);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}resolveDegradedEvidence(e,t){let r=this.get(e),o=r?.evidenceDegradations.find(s=>s.obligationId===t);if(!r||!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,t,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(d=>d.obligationId===t);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${X(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",X(e))}appendEvidenceEvent(e,t,r){let o=this.evidenceJournalDir(e);mkdirSync(o,{recursive:true,mode:448});let i=createHash("sha256").update(r).digest("hex"),s=join$1(o,`${t.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(d){if(d.code!=="EEXIST")throw d}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=Z(e.evidenceObligations),e.evidenceDegradations=Q(e.evidenceDegradations),e.evidenceOutcomes=ee(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync(t))return;let r;try{r=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let o=r.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Ge(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||te(i.kind)-te(s.kind));for(let i of o)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let r=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(r)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let o=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!o||r||o.correctionFingerprint===t.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=t.at,o.correctionFingerprint=t.fingerprint,o.violations=t.violations;return}let i=o?.attempt??r?.attempt??0;if(t.kind==="resolve"&&r?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(r)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:o?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),r=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384}),renameSync(r,t);}};function Z(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!oe(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:re(t.contractId),o=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function Q(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function ee(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Ge(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let o={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:re(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return oe(e.contract)?{kind:t,...o,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...o,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...o}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...o,reason:e.reason}:null}function te(n){return n==="add"?0:n==="correction"?1:2}function oe(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,r=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function We(n){let e=n.trim().replace(/^\//,"");if(!e.startsWith("devflow:"))return null;let t=e.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(t)?`devflow:${t.toLowerCase()}`:null}function ie(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=We(e[1]);return t?{rawName:e[1],skillName:t}:null}var p=emitSemanticControlLog;var tt=2,nt=1;function rt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function se(n=rt()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync(t))continue;let r=JSON.parse(readFileSync$1(t,"utf8"));if(r.version!==tt&&r.version!==nt||!ot(r.commands)){p({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:t}});continue}return r.commands}catch(r){p({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:r.message,fallback:"next_registry_candidate"}});}return null}function ot(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(e=>{if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return E(t.mcpTools)&&E(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||E(t.runtimePackages))&&(t.hostTools===void 0||it(t.hostTools))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function it(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([e,t])=>e.length>0&&E(t))}function E(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}var ut={react:["react","react-dom"],nextjs:["next","react"],vue:["vue"],nest:["@nestjs/core"],tailwind:["tailwindcss"],taro:["@tarojs/taro"],electron:["electron"],graphql:["graphql"]};function lt(n,e){let t=join(n,"package.json"),r=ue(t),o=ht(r,e),i=join(n,"package-lock.json"),s=ue(i),a=vt(s,e);return a?{packageName:e,...o?{declaredRange:o}:{},resolvedVersion:a,evidencePath:relative(n,i)||"package-lock.json",confidence:"high"}:o?{packageName:e,declaredRange:o,evidencePath:relative(n,t)||"package.json",confidence:"medium"}:{packageName:e,confidence:"unknown"}}function le(n,e,t={}){let r=n.replace(/^devflow:/,"").split(":").pop()??n,o=(ut[r]??[]).map(a=>lt(e,a)),i=t.rolloutMode??resolveCapabilityRollout(e).config.learningOverlays;if(i==="off")return {skillName:n,projectRoot:e,packages:o,learned:[],shadowEligible:[],rolloutMode:i};let s=t.database??openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let d=s.listLearningCandidates({projectRoot:e,states:["shadow","evaluated","active"],limit:100}).filter(c=>c.projectRoot===e||c.scope==="global").filter(c=>!c.expiresAt||c.expiresAt>(t.now??Date.now())).filter(c=>ft(c,n,t)).sort((c,f)=>f.confidence-c.confidence||f.updatedAt-c.updatedAt),m=pt(d.map(c=>mt(c,c.state==="active"?"active":"shadow")),t),l=i==="on"?m.filter(c=>c.state==="active"):[],u=m.filter(c=>c.state==="shadow"||i==="shadow");try{s.insertEvent({kind:"learning_overlay_match",timestamp:Date.now(),success:!0,metadata:{projectRoot:e,skillName:n,rolloutMode:i,eligible:m.map(c=>`${c.candidateId}@${c.version}`),injected:l.map(c=>`${c.candidateId}@${c.version}`)}});}catch{}return {skillName:n,projectRoot:e,packages:o,learned:l,shadowEligible:u,rolloutMode:i}}finally{t.database||s.close();}}function me(n){let e=[],t=n.packages.map(r=>{let o=r.resolvedVersion??r.declaredRange??"unknown";return `${r.packageName}=${o} (confidence=${r.confidence}${r.evidencePath?`, source=${r.evidencePath}`:""})`}).join("; ");return t&&e.push(`DevFlow runtime project-version evidence for ${n.skillName}: ${t}. Treat target-project evidence as authoritative; do not apply a hardcoded framework version.`),n.learned.length>0&&e.push([`DevFlow governed project instructions for ${n.skillName}:`,...n.learned.map(r=>`- ${r.instruction}`),"Apply only to this request and keep canonical Skill/MCP requirements unchanged."].join(`
|
|
1
|
+
import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,resolveProjectCapabilityProfile,resolveCapabilityRollout,claudeCodeRuntimeAdapter,semanticTextHash,stableRuntimeHash,resolveRuntimeActivationSnapshot,getProjectStateDir,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,readRuntimeState}from'@devflow-tools/sdk';import {existsSync,readFileSync as readFileSync$1,rmSync,mkdirSync,writeFileSync,linkSync,readdirSync,renameSync,unlinkSync}from'fs';import {join as join$1,dirname}from'path';import {randomUUID,createHash}from'crypto';import {fileURLToPath}from'url';import {emitSemanticControlLog,SemanticRuntimeEventProjector,rotateDiagnosticLogFile}from'@devflow-tools/telemetry';import {readFileSync,openSync,constants,fstatSync,closeSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,renameSync as renameSync$1,realpathSync,existsSync as existsSync$1,appendFileSync}from'node:fs';import {join,resolve,relative}from'node:path';import {request}from'node:http';import {createHash as createHash$1,randomUUID as randomUUID$1}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';function h(n,e,t){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var K="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function B(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Je(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function k(n){return getProjectStateDir(Je(n))}function X(n){return Buffer.from(n,"utf8").toString("base64url")}function Be(n,e,t){let r=e?.trim();if(r){let o=/^[a-zA-Z0-9:._-]{1,192}$/.test(r)?r:`tool-${createHash("sha256").update(r.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${o}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function re(n){return `${n}:legacy-journal`}var x=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(k(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),o.skillName=t,o.requiredMcpTools=[...new Set(r)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(e,t){let r=this.registerSession(e);return r.contextInitialization={startedAt:Date.now(),...t?{toolUseId:t}:{}},r.lastActivityAt=Date.now(),this.persist(r),r}completeContextInitialization(e,t){let r=this.get(e);return r?(t&&r.contextInitialization?.toolUseId&&r.contextInitialization.toolUseId!==t||(delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r)),r):null}bindTaskIdentity(e,t){let r=this.registerSession(e);return r.activeTurnId=t.turnId,r.activeRequestId=t.requestId,r.intentArtifactHash=t.intentArtifactHash,r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let r=this.sessions.get(t);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(t);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=Z(i.evidenceObligations),i.evidenceDegradations=Q(i.evidenceDegradations),i.evidenceOutcomes=ee(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let r=structuredClone(t);return delete t.executionId,delete t.skillName,delete t.contextInitialization,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),r}addEvidenceObligation(e,t,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(m=>m.contractId===t.id))?.obligationId??Be(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:r,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let d=i.evidenceObligations.find(m=>m.obligationId===a);return d?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(d)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,r,o,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(l=>l.obligationId===t);if(!s||!a)return null;let d=/^[a-f0-9]{64}$/.test(o)?o:"";if(!d)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:d,violations:r.slice(0,16).map(l=>l.slice(0,240))},`correction\0${t}\0${d}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let m=s.evidenceObligations.find(l=>l.obligationId===t);return m?structuredClone(m):null}resolveEvidenceObligation(e,t){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===t);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}resolveDegradedEvidence(e,t){let r=this.get(e),o=r?.evidenceDegradations.find(s=>s.obligationId===t);if(!r||!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:o.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,t,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(d=>d.obligationId===t);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${X(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",X(e))}appendEvidenceEvent(e,t,r){let o=this.evidenceJournalDir(e);mkdirSync(o,{recursive:true,mode:448});let i=createHash("sha256").update(r).digest("hex"),s=join$1(o,`${t.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(d){if(d.code!=="EEXIST")throw d}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=Z(e.evidenceObligations),e.evidenceDegradations=Q(e.evidenceDegradations),e.evidenceOutcomes=ee(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync(t))return;let r;try{r=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let o=r.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Ge(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||te(i.kind)-te(s.kind));for(let i of o)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let r=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(r)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let o=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!o||r||o.correctionFingerprint===t.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=t.at,o.correctionFingerprint=t.fingerprint,o.violations=t.violations;return}let i=o?.attempt??r?.attempt??0;if(t.kind==="resolve"&&r?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(r)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:o?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),r=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384}),renameSync(r,t);}};function Z(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!oe(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:re(t.contractId),o=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function Q(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function ee(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Ge(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let o={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:re(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return oe(e.contract)?{kind:t,...o,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...o,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...o}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...o,reason:e.reason}:null}function te(n){return n==="add"?0:n==="correction"?1:2}function oe(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,r=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(r)&&r.length<=16&&r.every(o=>typeof o=="string"&&o.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function We(n){let e=n.trim().replace(/^\//,"");if(!e.startsWith("devflow:"))return null;let t=e.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(t)?`devflow:${t.toLowerCase()}`:null}function ie(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=We(e[1]);return t?{rawName:e[1],skillName:t}:null}var p=emitSemanticControlLog;var tt=2,nt=1;function rt(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{return join$1(dirname(fileURLToPath(import.meta.url)),"..","..")}catch{return process.cwd()}}function se(n=rt()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync(t))continue;let r=JSON.parse(readFileSync$1(t,"utf8"));if(r.version!==tt&&r.version!==nt||!ot(r.commands)){p({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:t}});continue}return r.commands}catch(r){p({event:"hook.runtime.degraded",identity:{projectRoot:process.env.CLAUDE_PROJECT_DIR||process.cwd()},level:"warn",timestamp:Date.now(),data:{stage:"command_registry",reason:r.message,fallback:"next_registry_candidate"}});}return null}function ot(n){return !n||typeof n!="object"||Array.isArray(n)?false:Object.values(n).every(e=>{if(!e||typeof e!="object"||Array.isArray(e))return false;let t=e;return E(t.mcpTools)&&E(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||E(t.runtimePackages))&&(t.hostTools===void 0||it(t.hostTools))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function it(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([e,t])=>e.length>0&&E(t))}function E(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}var ut={react:["react","react-dom"],nextjs:["next","react"],vue:["vue"],nest:["@nestjs/core"],tailwind:["tailwindcss"],taro:["@tarojs/taro"],electron:["electron"],graphql:["graphql"]};function lt(n,e){let t=join(n,"package.json"),r=ue(t),o=ht(r,e),i=join(n,"package-lock.json"),s=ue(i),a=vt(s,e);return a?{packageName:e,...o?{declaredRange:o}:{},resolvedVersion:a,evidencePath:relative(n,i)||"package-lock.json",confidence:"high"}:o?{packageName:e,declaredRange:o,evidencePath:relative(n,t)||"package.json",confidence:"medium"}:{packageName:e,confidence:"unknown"}}function le(n,e,t={}){let r=n.replace(/^devflow:/,"").split(":").pop()??n,o=(ut[r]??[]).map(a=>lt(e,a)),i=t.rolloutMode??resolveCapabilityRollout(e).config.learningOverlays;if(i==="off")return {skillName:n,projectRoot:e,packages:o,learned:[],shadowEligible:[],rolloutMode:i};let s=t.database??openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let d=s.listLearningCandidates({projectRoot:e,states:["shadow","evaluated","active"],limit:100}).filter(c=>c.projectRoot===e||c.scope==="global").filter(c=>!c.expiresAt||c.expiresAt>(t.now??Date.now())).filter(c=>ft(c,n,t)).sort((c,f)=>f.confidence-c.confidence||f.updatedAt-c.updatedAt),m=pt(d.map(c=>mt(c,c.state==="active"?"active":"shadow")),t),l=i==="on"?m.filter(c=>c.state==="active"):[],u=m.filter(c=>c.state==="shadow"||i==="shadow");try{s.insertEvent({kind:"learning_overlay_match",timestamp:Date.now(),success:!0,metadata:{projectRoot:e,skillName:n,rolloutMode:i,eligible:m.map(c=>`${c.candidateId}@${c.version}`),injected:l.map(c=>`${c.candidateId}@${c.version}`)}});}catch{}return {skillName:n,projectRoot:e,packages:o,learned:l,shadowEligible:u,rolloutMode:i}}finally{t.database||s.close();}}function me(n){let e=[],t=n.packages.map(r=>{let o=r.resolvedVersion??r.declaredRange??"unknown";return `${r.packageName}=${o} (confidence=${r.confidence}${r.evidencePath?`, source=${r.evidencePath}`:""})`}).join("; ");return t&&e.push(`DevFlow runtime project-version evidence for ${n.skillName}: ${t}. Treat target-project evidence as authoritative; do not apply a hardcoded framework version.`),n.learned.length>0&&e.push([`DevFlow governed project instructions for ${n.skillName}:`,...n.learned.map(r=>`- ${r.instruction}`),"Apply only to this request and keep canonical Skill/MCP requirements unchanged."].join(`
|
|
2
2
|
`)),e.join(`
|
|
3
|
-
`)}function mt(n,e){return {candidateId:n.id,version:n.overlayVersion,state:e,instruction:n.instruction,trigger:n.trigger,confidence:n.confidence,evidenceReceipt:n.graderReceipt??`candidate:${n.id}:v${n.overlayVersion}`,expiresAt:n.expiresAt}}function pt(n,e){let t=Math.max(0,Math.min(e.maxLearnedEntries??3,3)),r=Math.max(0,Math.min(e.learnedCharacterBudget??1600,4e3)),o=[],i=0;for(let s of n){if(o.length>=t)break;let a=s.instruction.length+4;i+a>r||(o.push(s),i+=a);}return o}function ft(n,e,t){let r=n.trigger,o=e.replace(/^devflow:/,"").split(":").pop()??e,i=A(r.skills);if(i.length>0&&!i.some(c=>c===e||c===o||c.endsWith(`:${o}`)))return false;let s=(t.prompt??"").normalize("NFKC").toLocaleLowerCase("en-US"),a=(t.command??"").normalize("NFKC").toLocaleLowerCase("en-US"),d=[...t.files??[],...gt(t.prompt??"")].map(c=>c.replaceAll("\\","/").toLocaleLowerCase("en-US")),m=A(r.commands).map(de);if(m.length>0&&!m.some(c=>a.includes(c)||s.includes(c)))return false;let l=A(r.entities).map(de);if(l.length>0&&!l.some(c=>s.includes(c)||a.includes(c)))return false;let u=A(r.files).map(c=>c.replaceAll("\\","/").toLocaleLowerCase("en-US"));return !(u.length>0&&!u.some(c=>d.some(f=>yt(f,c))))}function gt(n){return n.match(/(?:^|\s)((?:src|app|apps|packages|plugins|lib|test|tests)\/[A-Za-z0-9_./@-]+)/gu)?.map(e=>e.trim())??[]}function yt(n,e){if(!e.includes("*"))return n===e||n.includes(e);let t=e.replace(/[.+?^${}()|[\]\\]/gu,"\\$&").replaceAll("*",".*");return new RegExp(`^${t}$`,"u").test(n)}function A(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"&&e.trim().length>0):[]}function de(n){return n.normalize("NFKC").trim().toLocaleLowerCase("en-US")}function ue(n){if(!existsSync$1(n))return null;try{let e=JSON.parse(readFileSync(n,"utf8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}function ht(n,e){for(let t of ["dependencies","devDependencies","peerDependencies","optionalDependencies"]){let r=n?.[t];if(!r||typeof r!="object"||Array.isArray(r))continue;let o=r[e];if(typeof o=="string"&&o.trim())return o.trim()}}function vt(n,e){let t=n?.packages;if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t[`node_modules/${e}`];if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o.version;if(typeof i=="string"&&i.trim())return i.trim()}}let r=n?.dependencies;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r[e];if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o.version;if(typeof i=="string"&&i.trim())return i.trim()}}}function pe(n){let e=se();return e?e[n]?.mcpTools??[]:[]}function fe(n,e,t){return me(le(n,e,{prompt:t}))}var
|
|
4
|
-
`;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(r)}),appendFileSync(t,r);}catch{}}function Ot(n){return new Promise(e=>setTimeout(e,n))}var ke=1e4,Ft=3e4,D=500,C=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=e?.database??null,this.ownsDatabase=!e?.database;let t=e?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(t)&&t>=0?t:100;}async sendEvent(e){let t={...e,input:this.truncateInput(e.input)};return this.commitOrCache("tool_call",t)?(this.postHttp("/api/telemetry/tool-call",t),e.eventId):null}async sendExecutionStart(e,t,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",r=Date.now(),o){let i={executionId:e,status:t,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,r){let o={id:e,projectRoot:t,startedAt:r,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),i}async completeEvent(e){let t=this.commitOrCache("complete_event",e);return t&&(this.postHttp("/api/telemetry/tool-call/output",e),this.scheduleMetricAggregation()),t}async endSession(e,t=Date.now()){let r={sessionId:e,finishedAt:t},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),o}async flushCache(){try{let t=this.getDatabase(),r=t.listTelemetryFailures({unresolvedOnly:!0,limit:D}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),t.resolveTelemetryFailure(o.id);}catch{}t.trimTelemetryFailures(D);}catch{}let e=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(t=>t.endsWith(".json")).map(t=>{let r=join$1(this.cacheDir,t);try{return {cacheFile:r,envelope:Ht(JSON.parse(readFileSync$1(r,"utf8")))}}catch{return null}}).filter(t=>t!==null).sort((t,r)=>t.envelope.timestamp-r.envelope.timestamp||we(t.envelope.operation)-we(r.envelope.operation));for(let{cacheFile:t,envelope:r}of e)try{let o=this.getDatabase();o.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),o.resolveTelemetryFailure(r.id),unlinkSync(t);}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(e,t){try{return this.applyOperation(e,t),!0}catch(r){return this.cacheOperation(e,t,r),false}}applyOperation(e,t){let r=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(r,t),r.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(r,t),r.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":r.ensureSession(t),r.insertRun({id:Se(t.id),source:"hook",tool:"session",input:{projectRoot:t.projectRoot},status:"active",startedAt:t.startedAt,tokenUsed:0,metadata:{sessionId:t.id,projectRoot:t.projectRoot}});return;case "complete_event":if(!r.updateToolCallEvent(t.eventId,{output:t.output===void 0?void 0:JSON.stringify(t.output),error:t.error,failureCategory:t.failureCategory,duration:t.duration}))throw new Error(`Tool call event ${t.eventId} is not available for completion`);return;case "session_end":r.closeSession(t.sessionId,t.finishedAt),r.updateRun(Se(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let r=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=typeof t.projectRoot=="string"&&t.projectRoot.trim()?t.projectRoot:typeof t.input?.projectRoot=="string"&&t.input.projectRoot.trim()?t.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";e.ensureSession({id:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:o}),s.trimTelemetryFailures(D),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-D)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Ft).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(e,t){he(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=ke?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,ke)}...`}}};function we(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Se(n){return `hook-run:${n}`}function Ht(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.id!="string"||typeof e.operation!="string"||e.payload===void 0||typeof e.failure!="string"||typeof e.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return e}var qt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ut=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Jt=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,zt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function w(n){let e=n.trim().replace(qt,"").trim();return !e||Ut.test(e)?null:(zt.exec(e)??Jt.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var T=1,Xt="memory-snapshot-v1.json",Zt=512*1024,Ee=256*1024,Ae=2e3,Qt=500,en=10,tn=240,nn=300*1e3,rn=720*60*60*1e3,on=2147483647;function sn(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function I(n){return resolve(n)}function S(n){return createHash$1("sha256").update(I(n)).digest("hex").slice(0,16)}function an(n,e={}){let t=S(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(I(n));return join(r,Xt)}function cn(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function H(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function dn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&H(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function un(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function Me(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=I(e),i=S(o),s=r.generation===void 0?0:r.generation;return r.version!==T||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>Ee||!H(r.memoryIds,Ae)||!Array.isArray(r.conflicts)||r.conflicts.length>Qt||!r.conflicts.every(dn)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+nn||!Number.isInteger(s)||s<0||s>on||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!un(r.degradation)?null:{...r,generation:s}}function ln(n,e,t,r,o=0){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function mn(n,e={}){let t=e.now??Date.now(),r=an(n,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>Zt)throw new Error("cache_size_invalid");let s=sn({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(o,"utf8")),d=Me(a,n,t);if(!d)throw new Error("cache_schema_invalid");return d.status==="ready"&&t-d.generatedAt>rn?{snapshot:{...d,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:d,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:ln(n,a?"pending":"degraded",a?"cache_missing":cn(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function pn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function fn(n,e,t){if(!e.trim())return null;try{let r=JSON.parse(e);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=Me(r.snapshot,n,t);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=Ee){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:H(r.memoryIds,Ae)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function F(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,tn).join("")}function gn(n){if(n.length===0)return "";let e=n.slice(0,en),t=e.map(r=>{let o=F(r.family,"unknown"),i=F(r.entity,"unknown"),s=F(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
3
|
+
`)}function mt(n,e){return {candidateId:n.id,version:n.overlayVersion,state:e,instruction:n.instruction,trigger:n.trigger,confidence:n.confidence,evidenceReceipt:n.graderReceipt??`candidate:${n.id}:v${n.overlayVersion}`,expiresAt:n.expiresAt}}function pt(n,e){let t=Math.max(0,Math.min(e.maxLearnedEntries??3,3)),r=Math.max(0,Math.min(e.learnedCharacterBudget??1600,4e3)),o=[],i=0;for(let s of n){if(o.length>=t)break;let a=s.instruction.length+4;i+a>r||(o.push(s),i+=a);}return o}function ft(n,e,t){let r=n.trigger,o=e.replace(/^devflow:/,"").split(":").pop()??e,i=A(r.skills);if(i.length>0&&!i.some(c=>c===e||c===o||c.endsWith(`:${o}`)))return false;let s=(t.prompt??"").normalize("NFKC").toLocaleLowerCase("en-US"),a=(t.command??"").normalize("NFKC").toLocaleLowerCase("en-US"),d=[...t.files??[],...gt(t.prompt??"")].map(c=>c.replaceAll("\\","/").toLocaleLowerCase("en-US")),m=A(r.commands).map(de);if(m.length>0&&!m.some(c=>a.includes(c)||s.includes(c)))return false;let l=A(r.entities).map(de);if(l.length>0&&!l.some(c=>s.includes(c)||a.includes(c)))return false;let u=A(r.files).map(c=>c.replaceAll("\\","/").toLocaleLowerCase("en-US"));return !(u.length>0&&!u.some(c=>d.some(f=>yt(f,c))))}function gt(n){return n.match(/(?:^|\s)((?:src|app|apps|packages|plugins|lib|test|tests)\/[A-Za-z0-9_./@-]+)/gu)?.map(e=>e.trim())??[]}function yt(n,e){if(!e.includes("*"))return n===e||n.includes(e);let t=e.replace(/[.+?^${}()|[\]\\]/gu,"\\$&").replaceAll("*",".*");return new RegExp(`^${t}$`,"u").test(n)}function A(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"&&e.trim().length>0):[]}function de(n){return n.normalize("NFKC").trim().toLocaleLowerCase("en-US")}function ue(n){if(!existsSync$1(n))return null;try{let e=JSON.parse(readFileSync(n,"utf8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}function ht(n,e){for(let t of ["dependencies","devDependencies","peerDependencies","optionalDependencies"]){let r=n?.[t];if(!r||typeof r!="object"||Array.isArray(r))continue;let o=r[e];if(typeof o=="string"&&o.trim())return o.trim()}}function vt(n,e){let t=n?.packages;if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t[`node_modules/${e}`];if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o.version;if(typeof i=="string"&&i.trim())return i.trim()}}let r=n?.dependencies;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r[e];if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o.version;if(typeof i=="string"&&i.trim())return i.trim()}}}function pe(n){let e=se();return e?e[n]?.mcpTools??[]:[]}function fe(n,e,t){return me(le(n,e,{prompt:t}))}var Mt=getLocalApiKey(),L=join(getDevFlowStateRoot(),"errors");async function he(n,e,t={}){let r=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Ct();if(!r)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,d=acquireRuntimeHttpCircuit(r,n);if(a&&!d.allowed)return {delivered:false,suppressed:true,fallbackReason:d.state.fallbackReason};let m;for(let u=0;u<=s;u+=1)try{return await Tt(r,n,e,o),a&®isterRuntimeHttpSuccess(r,n).transitioned&&h("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:d.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(c){m=c instanceof Error?c:new Error(String(c)),u<s&&await Ot(Math.min(100*2**u,1e3));}if(!m)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return ge(n,m),{delivered:false,suppressed:false,fallbackReason:m.message};let l=registerRuntimeHttpFailure(r,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return l.transitioned&&(ge(n,m),h("http_circuit_transition",{endpoint:r,path:new URL(n,r).pathname,previous:d.state.status,status:"open",failures:l.state.failures,openUntil:l.state.openUntil,fallbackReason:l.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:l.state.fallbackReason}}function Ct(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function Tt(n,e,t,r){return new Promise((o,i)=>{let s=JSON.stringify(t),a=new URL(e,n),d=false,m=u=>{d||(d=true,u?i(u):o());},l=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Mt,"Content-Length":Buffer.byteLength(s)},timeout:r},u=>{u.on("error",m),u.on("end",()=>{let c=u.statusCode??0;m(c>=200&&c<300?void 0:new Error(`HTTP ${c}`));}),u.resume();});l.on("error",m),l.on("timeout",()=>l.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),l.write(s),l.end();})}function ge(n,e){try{existsSync$1(L)||mkdirSync$1(L,{recursive:!0});let t=join(L,"http-errors.log"),r=`${new Date().toISOString()} | ${n} | ${e.message}
|
|
4
|
+
`;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(r)}),appendFileSync(t,r);}catch{}}function Ot(n){return new Promise(e=>setTimeout(e,n))}var ke=1e4,Ft=3e4,M=500,C=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(getDevFlowStateRoot(),"global","telemetry-cache"),this.database=e?.database??null,this.ownsDatabase=!e?.database;let t=e?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(t)&&t>=0?t:100;}async sendEvent(e){let t={...e,input:this.truncateInput(e.input)};return this.commitOrCache("tool_call",t)?(this.postHttp("/api/telemetry/tool-call",t),e.eventId):null}async sendExecutionStart(e,t,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",r=Date.now(),o){let i={executionId:e,status:t,finishedAt:r,metadata:o},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,r){let o={id:e,projectRoot:t,startedAt:r,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),i}async completeEvent(e){let t=this.commitOrCache("complete_event",e);return t&&(this.postHttp("/api/telemetry/tool-call/output",e),this.scheduleMetricAggregation()),t}async endSession(e,t=Date.now()){let r={sessionId:e,finishedAt:t},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),o}async flushCache(){try{let t=this.getDatabase(),r=t.listTelemetryFailures({unresolvedOnly:!0,limit:M}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),t.resolveTelemetryFailure(o.id);}catch{}t.trimTelemetryFailures(M);}catch{}let e=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(t=>t.endsWith(".json")).map(t=>{let r=join$1(this.cacheDir,t);try{return {cacheFile:r,envelope:Ht(JSON.parse(readFileSync$1(r,"utf8")))}}catch{return null}}).filter(t=>t!==null).sort((t,r)=>t.envelope.timestamp-r.envelope.timestamp||we(t.envelope.operation)-we(r.envelope.operation));for(let{cacheFile:t,envelope:r}of e)try{let o=this.getDatabase();o.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),o.resolveTelemetryFailure(r.id),unlinkSync(t);}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(e,t){try{return this.applyOperation(e,t),!0}catch(r){return this.cacheOperation(e,t,r),false}}applyOperation(e,t){let r=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(r,t),r.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(r,t),r.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":r.ensureSession(t),r.insertRun({id:Se(t.id),source:"hook",tool:"session",input:{projectRoot:t.projectRoot},status:"active",startedAt:t.startedAt,tokenUsed:0,metadata:{sessionId:t.id,projectRoot:t.projectRoot}});return;case "complete_event":if(!r.updateToolCallEvent(t.eventId,{output:t.output===void 0?void 0:JSON.stringify(t.output),error:t.error,failureCategory:t.failureCategory,duration:t.duration}))throw new Error(`Tool call event ${t.eventId} is not available for completion`);return;case "session_end":r.closeSession(t.sessionId,t.finishedAt),r.updateRun(Se(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let r=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=typeof t.projectRoot=="string"&&t.projectRoot.trim()?t.projectRoot:typeof t.input?.projectRoot=="string"&&t.input.projectRoot.trim()?t.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";e.ensureSession({id:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:o}),s.trimTelemetryFailures(M),this.scheduleRetry();return}catch{}try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${o}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimRetryCache(),this.scheduleRetry();}catch{}}trimRetryCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-M)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Ft).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(e,t){he(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=ke?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,ke)}...`}}};function we(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Se(n){return `hook-run:${n}`}function Ht(n){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let e=n;if(typeof e.id!="string"||typeof e.operation!="string"||e.payload===void 0||typeof e.failure!="string"||typeof e.timestamp!="number")throw new Error("Invalid telemetry cache envelope");return e}var qt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ut=/\b(?:(?:do\s+not|don't|dont|never|not)(?:\s+need\s+to)?|no\s+need\s+to)\s+(?:please\s+)?(?:remember|memorize)\b|(?:不要|别|不用|无需|不必|不需要)(?:再)?(?:记住|记|记忆)/iu,Jt=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,zt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function w(n){let e=n.trim().replace(qt,"").trim();return !e||Ut.test(e)?null:(zt.exec(e)??Jt.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var T=1,Xt="memory-snapshot-v1.json",Zt=512*1024,Ee=256*1024,Ae=2e3,Qt=500,en=10,tn=240,nn=300*1e3,rn=720*60*60*1e3,on=2147483647;function sn(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function I(n){return resolve(n)}function S(n){return createHash$1("sha256").update(I(n)).digest("hex").slice(0,16)}function an(n,e={}){let t=S(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(I(n));return join(r,Xt)}function cn(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function H(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function dn(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&H(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function un(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function De(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let r=n,o=I(e),i=S(o),s=r.generation===void 0?0:r.generation;return r.version!==T||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>Ee||!H(r.memoryIds,Ae)||!Array.isArray(r.conflicts)||r.conflicts.length>Qt||!r.conflicts.every(dn)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+nn||!Number.isInteger(s)||s<0||s>on||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!un(r.degradation)?null:{...r,generation:s}}function ln(n,e,t,r,o=0){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function mn(n,e={}){let t=e.now??Date.now(),r=an(n,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>Zt)throw new Error("cache_size_invalid");let s=sn({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(o,"utf8")),d=De(a,n,t);if(!d)throw new Error("cache_schema_invalid");return d.status==="ready"&&t-d.generatedAt>rn?{snapshot:{...d,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:d,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:ln(n,a?"pending":"degraded",a?"cache_missing":cn(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function pn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function fn(n,e,t){if(!e.trim())return null;try{let r=JSON.parse(e);if(r.status!=="ok"&&r.status!=="degraded")return null;if(r.enabled===!1){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=De(r.snapshot,n,t);if(o)return o;if(r.status==="ok"&&typeof r.markdown=="string"&&r.markdown.length>0&&Buffer.byteLength(r.markdown,"utf8")<=Ee){let i=I(n);return {version:T,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:H(r.memoryIds,Ae)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function F(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,tn).join("")}function gn(n){if(n.length===0)return "";let e=n.slice(0,en),t=e.map(r=>{let o=F(r.family,"unknown"),i=F(r.entity,"unknown"),s=F(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
5
5
|
${t.join(`
|
|
6
6
|
`)}`}function yn(n){let e=n.now??Date.now();if(pn(n.configPath)===false)return "";let t=fn(n.projectRoot,n.daemonResponse??"",e),r=t?{snapshot:t,source:"daemon"}:mn(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
|
|
7
7
|
DevFlow memory snapshot=pending; source=${r.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(o.generatedAt).toISOString(),s=o.degradation?.reason?`; reason=${o.degradation.reason}`:"",a=`DevFlow memory snapshot=${o.status}; source=${r.source}; generatedAt=${i}${s}.`,d=gn(o.conflicts);return o.markdown?[o.markdown,d,a].filter(Boolean).join(`
|
|
8
8
|
`):["## Project memory",d,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
9
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(yn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function b(n){let{projectRoot:e,...t}=n;try{return new q(e).dispatchBoundary(t).snapshot??null}catch(r){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:r instanceof Error?r.message:String(r),tool:n.producer}}),null}}var q=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=kn(e.kind,e.payload??{});if(!t)return {handled:false};let r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=bn(r,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return o?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(r),new SemanticRuntimeEventProjector).dispatch({definition:o.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${o.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{r.close();}}};function bn(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,r=e.turnId??t?.canonicalAction?.binding.turnId,o=e.requestId??t?.requestId;if(!r&&!o)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(d=>r?d.turnId===r:d.requestId===o);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function kn(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var Sn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,Rn=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,_n=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,xn=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function En(n){let e=n.trim();return e.length>0&&!Sn.test(e)}function An(n){let e=n.normalize("NFKC").trim(),t=xn.test(e);return e.length>=4&&(_n.test(e)||t)&&(!Rn.test(e)||t)&&w(e)===null}function Mn(n,e,t=Date.now()){let r=createHash$1("sha256").update(e.trim()).digest("hex"),o=createHash$1("sha256").update(`${n}\0${t}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:t}}function Ce(n,e,t=[]){return `memory-receipt:${createHash$1("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Dn(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function U(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,r=n.status==="committed"?"; indexStatus=pending":"",o=n.memoryIds.some(a=>a.startsWith("raw-memory:")),i=n.status==="committed"&&n.source==="explicit_intent"&&!o?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":n.status==="committed"&&n.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=n.status==="committed"&&n.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call mcp__devflow__memory_commit_turn once with turnId=${n.turnId} and semantic candidates. Split every distinct reusable fact into a durable_memory candidate, classify instructions that apply only to this turn as turn_constraint, and include evidenceSpans copied verbatim from the user prompt for every candidate. Preserve exact flags, package names, versions, paths, and identifiers. Keep narrative and value in the user prompt language; do not translate evidence into a different surface form. The tool refines the existing receipt idempotently; it must not create native Claude memory. If refinement is unavailable, return the existing canonical receipt without claiming refinement.`:"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${r}${i}.`+s}function Te(n){if(!En(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),r=createHash$1("sha256").update(t).digest("hex"),o=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(u=>u.promptHash===r&&Date.now()-u.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:n.identity??Mn(n.sessionId,t),s=o??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:U(s),skipSkillRouting:s.source==="explicit_intent"};let d=(n.activation?.semantic??"degraded_structural")==="degraded_structural"?w(t)??void 0:void 0;if(!d&&An(t)){let u=Ce(s.turnId,"skipped"),c=e.skipMemoryTurn({turnId:s.turnId,receiptId:u,source:"automatic_transient_skip",reason:"high_confidence_transient_task"});return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.skipped",payload:{receiptId:u,reasonCode:"high_confidence_transient_task"},dedupeKey:u,producer:"devflow-memory-turn"}),p({event:"memory.semantic.decided",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId},level:"info",timestamp:Date.now(),data:{status:"semantic_empty",operation:"none",reason:"high_confidence_transient_task"}}),{turn:c,additionalContext:U(c),skipSkillRouting:!1}}let m=d?"commit_explicit":"capture_prompt",l=e.enqueueWork({idempotencyKey:`memory-turn:${m}:${s.turnId}`,kind:d?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:m,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:d,createdAt:s.createdAt}});if(d){let u=`raw-memory:${createHash$1("sha256").update(`${n.projectRoot}\0${i.turnId}\0${d}`).digest("hex").slice(0,24)}`,c=Ce(s.turnId,"committed",[u]),f=e.commitMemoryTurn({turnId:s.turnId,receiptId:c,memoryIds:[u],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:l.id,obligation:"memory"},dedupeKey:`${l.id}:owned`,producer:"devflow-memory-turn"}),b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:c,reasonCode:"explicit_raw_queued"},dedupeKey:c,producer:"devflow-memory-turn"}),p({event:"memory.write.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,actionReceipt:c},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:u,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:f,explicitContent:d,additionalContext:U(f),skipSkillRouting:!0}}return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.pending",payload:{reasonCode:"semantic_decision_queued"},dedupeKey:`${s.turnId}:pending`,producer:"devflow-memory-turn"}),b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:l.id,obligation:"memory"},dedupeKey:`${l.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:d,additionalContext:Dn(s),skipSkillRouting:!1}}finally{e.close();}}function je(n,e){let t=$n(n);mkdirSync$1(t,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,o=join(t,`${r}.json`),i=`${o}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync$1(i,o),r}function $n(n){return join(k(n),"memory-turn-pending")}function $e(n){let e=Date.now();try{let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let r=`context-prefetch:${createHash$1("sha256").update(`${n.projectRoot}\0${n.sessionId}\0${n.executionId}\0${Ln(n.prompt)}\0${n.profileFingerprint}`).digest("hex")}`,o=t.enqueueWork({idempotencyKey:r,kind:"context.prefetch",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:n,maxAttempts:3});return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:!0,workState:o.state,latencyMs:Date.now()-e}),{accepted:!0,workItemId:o.id}}finally{t.close();}}catch(t){let r=t instanceof Error?t.message:String(t);return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:false,reason:r,latencyMs:Date.now()-e}),{accepted:false,reason:r}}}function Ln(n){return n.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}async function Fe(n){let e=Date.now(),t=Xn(n.projectRoot),r=claudeCodeRuntimeAdapter.normalizePrompt(n.hostEvent??{session_id:n.sessionId,prompt:n.prompt},{projectRoot:t}),o=semanticTextHash(Le(r.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:t,sessionId:n.sessionId,sourceHash:o});if(s){let j=Pe(s).identity,V=i.getRuntimeActivation(j.projectRoot,j.sessionId,j.turnId,s.version);if(!V)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:Pe(s),memoryIdentity:Ne(s),activation:V,reused:!0}}let a=`turn:${O(`${n.sessionId}\0${o}`)}`,d=`request:${O(`${t}\0${n.sessionId}\0${a}`)}`,m={projectRoot:t,projectId:`project:${stableRuntimeHash(t).slice(0,20)}`,hostId:r.hostId,sessionId:n.sessionId,executionId:n.sessionId,turnId:a,requestId:d},l=1,u=resolveRuntimeActivationSnapshot({projectRoot:t,createdAt:r.timestamp}),c=Wn(r.rawPrompt),f={identity:m,version:l,rawPrompt:r.rawPrompt,normalizedPrompt:Le(r.rawPrompt),...r.command?{command:r.command}:{},slashArgs:r.slashArgs,...r.activeSkill?{activeSkill:r.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:c,policyConstraints:[],classificationEvidence:[],sourceEventIds:[r.sourceEventId??`host-event:${o.slice(0,24)}`],sourceHash:o,createdAt:r.timestamp},y={...f,artifactHash:Zn(f)};i.appendTaskIntentArtifact(Bn(y)),i.bindRuntimeActivation({identity:m,revision:l,snapshot:u});let He=Kn(i,y);return p({event:"host.prompt.normalized",identity:m,level:"info",timestamp:Date.now(),data:{sourceHash:o,command:y.command,activeSkill:y.activeSkill,rawPromptBytes:Buffer.byteLength(y.rawPrompt)}}),p({event:"intent.artifact.created",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:y.artifactHash,targetCount:c.length}}),p({event:"intent.artifact.persisted",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:y.artifactHash,version:y.version,sourceHash:y.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-e}}),p({event:"terminal.transition.persisted",identity:m,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:He,sourceIntentHash:y.artifactHash}}),{artifact:y,memoryIdentity:Ne(y),activation:u,reused:!1}}finally{i.close();}}function Kn(n,e){let t=n.getLatestTerminalTransition(e.identity.projectRoot,e.identity.sessionId,e.identity.turnId);if(t)return t.receiptId;let r=`terminal:${O(`${e.artifactHash}\0open`)}`;return n.appendTerminalTransition({...e.identity,sequence:1,toState:"open",receiptId:r,reason:"host_prompt_accepted",payload:{sourceHash:e.sourceHash},createdAt:e.createdAt}),n.appendTerminalTransition({...e.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${O(`${e.artifactHash}\0intent_bound`)}`,sourceReceiptId:r,reason:"immutable_intent_persisted",payload:{intentArtifactHash:e.artifactHash},createdAt:Math.max(e.createdAt,Date.now())}).receiptId}function Bn(n){return {...n.identity,version:n.version,supersedesHash:n.supersedesHash,rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,command:n.command,slashArgs:n.slashArgs,activeSkill:n.activeSkill,intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence.map(e=>({...e})),sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function Pe(n){return {identity:Gn(n),version:n.version,...n.supersedesHash?{supersedesHash:n.supersedesHash}:{},rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,...n.command?{command:n.command}:{},slashArgs:n.slashArgs,...n.activeSkill?{activeSkill:n.activeSkill}:{},intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence,sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function Gn(n){return {projectRoot:n.projectRoot,projectId:n.projectId,hostId:n.hostId,sessionId:n.sessionId,turnId:n.turnId,requestId:n.requestId,...n.executionId?{executionId:n.executionId}:{}}}function Ne(n){let e=n.rawPrompt.trim().slice(0,4e3),t="identity"in n?n.identity.turnId:n.turnId;return {turnId:t,eventId:`memory-turn:${t.replace(/^turn:/u,"")}`,promptHash:createHash$1("sha256").update(e).digest("hex"),createdAt:n.createdAt}}function Wn(n){let e=n.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return Yn(e.map(t=>t.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(t=>!t.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(t))).slice(0,16)}function Le(n){return n.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function Yn(n){return [...new Set(n.filter(Boolean))]}function Xn(n){let e=resolve(n);try{return realpathSync(e)}catch{return e}}function Zn(n){return createHash$1("sha256").update(J(n)).digest("hex")}function O(n){return createHash$1("sha256").update(n).digest("hex").slice(0,24)}function J(n){if(n===null||typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="number")return Number.isFinite(n)?JSON.stringify(n):"null";if(Array.isArray(n))return `[${n.map(J).join(",")}]`;if(!n||typeof n!="object")return JSON.stringify(String(n));let e=n;return `{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${J(e[t])}`).join(",")}}`}var g=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function tr(n){let e=B()?[K]:[],t;try{t=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
9
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(yn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function b(n){let{projectRoot:e,...t}=n;try{return new q(e).dispatchBoundary(t).snapshot??null}catch(r){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:r instanceof Error?r.message:String(r),tool:n.producer}}),null}}var q=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=kn(e.kind,e.payload??{});if(!t)return {handled:false};let r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=bn(r,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return o?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(r),new SemanticRuntimeEventProjector).dispatch({definition:o.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${o.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{r.close();}}};function bn(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,r=e.turnId??t?.canonicalAction?.binding.turnId,o=e.requestId??t?.requestId;if(!r&&!o)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(d=>r?d.turnId===r:d.requestId===o);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function kn(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var Sn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,Rn=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,_n=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,xn=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function En(n){let e=n.trim();return e.length>0&&!Sn.test(e)}function An(n){let e=n.normalize("NFKC").trim(),t=xn.test(e);return e.length>=4&&(_n.test(e)||t)&&(!Rn.test(e)||t)&&w(e)===null}function Dn(n,e,t=Date.now()){let r=createHash$1("sha256").update(e.trim()).digest("hex"),o=createHash$1("sha256").update(`${n}\0${t}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:t}}function Ce(n,e,t=[]){return `memory-receipt:${createHash$1("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Mn(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function U(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,r=n.status==="committed"?"; indexStatus=pending":"",o=n.memoryIds.some(a=>a.startsWith("raw-memory:")),i=n.status==="committed"&&n.source==="explicit_intent"&&!o?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":n.status==="committed"&&n.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=n.status==="committed"&&n.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call mcp__devflow__memory_commit_turn once with turnId=${n.turnId} and semantic candidates. Split every distinct reusable fact into a durable_memory candidate, classify instructions that apply only to this turn as turn_constraint, and include evidenceSpans copied verbatim from the user prompt for every candidate. Preserve exact flags, package names, versions, paths, and identifiers. Keep narrative and value in the user prompt language; do not translate evidence into a different surface form. The tool refines the existing receipt idempotently; it must not create native Claude memory. If refinement is unavailable, return the existing canonical receipt without claiming refinement.`:"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${r}${i}.`+s}function Te(n){if(!En(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),r=createHash$1("sha256").update(t).digest("hex"),o=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(u=>u.promptHash===r&&Date.now()-u.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:n.identity??Dn(n.sessionId,t),s=o??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:U(s),skipSkillRouting:s.source==="explicit_intent"};let d=(n.activation?.semantic??"degraded_structural")==="degraded_structural"?w(t)??void 0:void 0;if(!d&&An(t)){let u=Ce(s.turnId,"skipped"),c=e.skipMemoryTurn({turnId:s.turnId,receiptId:u,source:"automatic_transient_skip",reason:"high_confidence_transient_task"});return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.skipped",payload:{receiptId:u,reasonCode:"high_confidence_transient_task"},dedupeKey:u,producer:"devflow-memory-turn"}),p({event:"memory.semantic.decided",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId},level:"info",timestamp:Date.now(),data:{status:"semantic_empty",operation:"none",reason:"high_confidence_transient_task"}}),{turn:c,additionalContext:U(c),skipSkillRouting:!1}}let m=d?"commit_explicit":"capture_prompt",l=e.enqueueWork({idempotencyKey:`memory-turn:${m}:${s.turnId}`,kind:d?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:m,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:d,createdAt:s.createdAt}});if(d){let u=`raw-memory:${createHash$1("sha256").update(`${n.projectRoot}\0${i.turnId}\0${d}`).digest("hex").slice(0,24)}`,c=Ce(s.turnId,"committed",[u]),f=e.commitMemoryTurn({turnId:s.turnId,receiptId:c,memoryIds:[u],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:l.id,obligation:"memory"},dedupeKey:`${l.id}:owned`,producer:"devflow-memory-turn"}),b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:c,reasonCode:"explicit_raw_queued"},dedupeKey:c,producer:"devflow-memory-turn"}),p({event:"memory.write.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,actionReceipt:c},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:u,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:f,explicitContent:d,additionalContext:U(f),skipSkillRouting:!0}}return b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.pending",payload:{reasonCode:"semantic_decision_queued"},dedupeKey:`${s.turnId}:pending`,producer:"devflow-memory-turn"}),b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:l.id,obligation:"memory"},dedupeKey:`${l.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:d,additionalContext:Mn(s),skipSkillRouting:!1}}finally{e.close();}}function je(n,e){let t=$n(n);mkdirSync$1(t,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,o=join(t,`${r}.json`),i=`${o}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync$1(i,o),r}function $n(n){return join(k(n),"memory-turn-pending")}function $e(n){let e=Date.now();try{let t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let r=`context-prefetch:${createHash$1("sha256").update(`${n.projectRoot}\0${n.sessionId}\0${n.executionId}\0${Ln(n.prompt)}\0${n.profileFingerprint}`).digest("hex")}`,o=t.enqueueWork({idempotencyKey:r,kind:"context.prefetch",projectRoot:n.projectRoot,sessionId:n.sessionId,payload:n,maxAttempts:3});return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:!0,workState:o.state,latencyMs:Date.now()-e}),{accepted:!0,workItemId:o.id}}finally{t.close();}}catch(t){let r=t instanceof Error?t.message:String(t);return h("prefetch_queue",{projectRoot:n.projectRoot,skillName:n.skillName,accepted:false,reason:r,latencyMs:Date.now()-e}),{accepted:false,reason:r}}}function Ln(n){return n.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}async function Fe(n){let e=Date.now(),t=Xn(n.projectRoot),r=claudeCodeRuntimeAdapter.normalizePrompt(n.hostEvent??{session_id:n.sessionId,prompt:n.prompt},{projectRoot:t}),o=semanticTextHash(Le(r.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:t,sessionId:n.sessionId,sourceHash:o});if(s){let j=Pe(s).identity,V=i.getRuntimeActivation(j.projectRoot,j.sessionId,j.turnId,s.version);if(!V)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:Pe(s),memoryIdentity:Ne(s),activation:V,reused:!0}}let a=`turn:${O(`${n.sessionId}\0${o}`)}`,d=`request:${O(`${t}\0${n.sessionId}\0${a}`)}`,m={projectRoot:t,projectId:`project:${stableRuntimeHash(t).slice(0,20)}`,hostId:r.hostId,sessionId:n.sessionId,executionId:n.sessionId,turnId:a,requestId:d},l=1,u=resolveRuntimeActivationSnapshot({projectRoot:t,createdAt:r.timestamp}),c=Wn(r.rawPrompt),f={identity:m,version:l,rawPrompt:r.rawPrompt,normalizedPrompt:Le(r.rawPrompt),...r.command?{command:r.command}:{},slashArgs:r.slashArgs,...r.activeSkill?{activeSkill:r.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:c,policyConstraints:[],classificationEvidence:[],sourceEventIds:[r.sourceEventId??`host-event:${o.slice(0,24)}`],sourceHash:o,createdAt:r.timestamp},y={...f,artifactHash:Zn(f)};i.appendTaskIntentArtifact(Bn(y)),i.bindRuntimeActivation({identity:m,revision:l,snapshot:u});let He=Kn(i,y);return p({event:"host.prompt.normalized",identity:m,level:"info",timestamp:Date.now(),data:{sourceHash:o,command:y.command,activeSkill:y.activeSkill,rawPromptBytes:Buffer.byteLength(y.rawPrompt)}}),p({event:"intent.artifact.created",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:y.artifactHash,targetCount:c.length}}),p({event:"intent.artifact.persisted",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:y.artifactHash,version:y.version,sourceHash:y.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-e}}),p({event:"terminal.transition.persisted",identity:m,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:He,sourceIntentHash:y.artifactHash}}),{artifact:y,memoryIdentity:Ne(y),activation:u,reused:!1}}finally{i.close();}}function Kn(n,e){let t=n.getLatestTerminalTransition(e.identity.projectRoot,e.identity.sessionId,e.identity.turnId);if(t)return t.receiptId;let r=`terminal:${O(`${e.artifactHash}\0open`)}`;return n.appendTerminalTransition({...e.identity,sequence:1,toState:"open",receiptId:r,reason:"host_prompt_accepted",payload:{sourceHash:e.sourceHash},createdAt:e.createdAt}),n.appendTerminalTransition({...e.identity,sequence:2,fromState:"open",toState:"intent_bound",receiptId:`terminal:${O(`${e.artifactHash}\0intent_bound`)}`,sourceReceiptId:r,reason:"immutable_intent_persisted",payload:{intentArtifactHash:e.artifactHash},createdAt:Math.max(e.createdAt,Date.now())}).receiptId}function Bn(n){return {...n.identity,version:n.version,supersedesHash:n.supersedesHash,rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,command:n.command,slashArgs:n.slashArgs,activeSkill:n.activeSkill,intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence.map(e=>({...e})),sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function Pe(n){return {identity:Gn(n),version:n.version,...n.supersedesHash?{supersedesHash:n.supersedesHash}:{},rawPrompt:n.rawPrompt,normalizedPrompt:n.normalizedPrompt,...n.command?{command:n.command}:{},slashArgs:n.slashArgs,...n.activeSkill?{activeSkill:n.activeSkill}:{},intent:n.intent,action:n.action,entities:n.entities,targetAnchors:n.targetAnchors,policyConstraints:n.policyConstraints,classificationEvidence:n.classificationEvidence,sourceEventIds:n.sourceEventIds,sourceHash:n.sourceHash,artifactHash:n.artifactHash,createdAt:n.createdAt}}function Gn(n){return {projectRoot:n.projectRoot,projectId:n.projectId,hostId:n.hostId,sessionId:n.sessionId,turnId:n.turnId,requestId:n.requestId,...n.executionId?{executionId:n.executionId}:{}}}function Ne(n){let e=n.rawPrompt.trim().slice(0,4e3),t="identity"in n?n.identity.turnId:n.turnId;return {turnId:t,eventId:`memory-turn:${t.replace(/^turn:/u,"")}`,promptHash:createHash$1("sha256").update(e).digest("hex"),createdAt:n.createdAt}}function Wn(n){let e=n.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return Yn(e.map(t=>t.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(t=>!t.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(t))).slice(0,16)}function Le(n){return n.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function Yn(n){return [...new Set(n.filter(Boolean))]}function Xn(n){let e=resolve(n);try{return realpathSync(e)}catch{return e}}function Zn(n){return createHash$1("sha256").update(J(n)).digest("hex")}function O(n){return createHash$1("sha256").update(n).digest("hex").slice(0,24)}function J(n){if(n===null||typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="number")return Number.isFinite(n)?JSON.stringify(n):"null";if(Array.isArray(n))return `[${n.map(J).join(",")}]`;if(!n||typeof n!="object")return JSON.stringify(String(n));let e=n;return `{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${J(e[t])}`).join(",")}}`}var g=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function tr(n){let e=B()?[K]:[],t;try{t=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
10
10
|
`)}:{}}}}let r=t.prompt||"";if(!r.trim())return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
11
11
|
`)}:{}}};let o=t.session_id?.trim(),i=ie(r),s=false,a,d,m=o?new x(g):void 0;if(o){try{d=await Fe({projectRoot:g,sessionId:o,prompt:r,hostEvent:t}),m.bindTaskIdentity(o,{turnId:d.artifact.identity.turnId,requestId:d.artifact.identity.requestId,intentArtifactHash:d.artifact.artifactHash}),e.push(`DevFlow immutable task identity: turnId=${d.artifact.identity.turnId}; requestId=${d.artifact.identity.requestId}; intentArtifactHash=${d.artifact.artifactHash}. Retrieval query expansion must not replace this original intent.`);}catch(l){e.push("DevFlow task intent persistence degraded; preserve the original user command and do not claim canonical context binding."),p({event:"intent.artifact.failed",identity:{projectRoot:g,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"user_prompt_submit",category:"intent_persistence_unavailable",error:l instanceof Error?l.message:String(l)}});}try{let l=Te({projectRoot:g,sessionId:o,prompt:r,...d?{identity:d.memoryIdentity}:{},...d?{activation:d.activation}:{}});l&&(e.push(l.additionalContext),s=l.skipSkillRouting);}catch(l){s=!!w(r);try{let u=je(g,{sessionId:o,prompt:r,createdAt:Date.now()});e.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${u}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),p({event:"memory.write.degraded",identity:{projectRoot:g,sessionId:o},level:"warn",timestamp:Date.now(),data:{stage:"turn_capture",reason:l.message,fallback:"durable_spool",receiptId:u}});}catch(u){e.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),p({event:"memory.write.degraded",identity:{projectRoot:g,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"turn_capture",reason:u.message,fallback:"none"}});}}}if(o&&i&&!s){let l=m.get(o)?.executionId,u=m.startExecution(o,i.skillName,pe(i.skillName));if(a=u.executionId,u.executionId&&u.executionId!==l){let f=new C;try{await f.sendSessionStart(o,g,u.startedAt),await f.sendExecutionStart(u.executionId,o,i.skillName,u.lastActivityAt,g,u.requiredMcpTools);}finally{f.close();}}let c=fe(i.skillName,g,r);c&&e.push(c);}if(o&&i&&a&&!s){let l=resolveProjectCapabilityProfile(g),u=resolveCapabilityRollout(g).config.retrievalSessions;$e({prompt:r.trimStart().replace(/^\/devflow:[a-z0-9][a-z0-9-]*\b/i,"").trim()||r,projectRoot:g,sessionId:o,executionId:a,skillName:i.skillName,profileFingerprint:l.fingerprint,rolloutMode:u,retrievalVersion:"r2.v1",createdAt:Date.now()});}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
12
12
|
`)}:{}}}}if(process.argv[1]?.endsWith("user-prompt-submit")||process.argv[1]?.endsWith("user-prompt-submit.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=await tr(e.trim()||process.argv[2]||"");n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>{n(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);}),setTimeout(()=>{n(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);},3e4).unref();}export{tr as handleUserPromptSubmit};
|
|
@@ -59,13 +59,16 @@ rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
|
|
|
59
59
|
## 开始案件
|
|
60
60
|
|
|
61
61
|
收到新的交付需求时,调用 `mcp__devflow__delivery_create_case`。使用当前项目绝对路径;默认 `baseRef=HEAD`、`targetRef=main`,除非用户明确指定其他值。为 actor、session、execution 和每次写操作生成稳定且可追踪的标识与幂等键。
|
|
62
|
+
- 若上下文检索发现同名组件、同一路由或多个框架实现,将候选路径通过 `existingImplementations` 传入创建案件参数,让案件先进入阻塞澄清;不要自行选择复用或替换。
|
|
62
63
|
|
|
63
64
|
## 推进规则
|
|
64
65
|
|
|
66
|
+
- 调用 `mcp__devflow__get_project_context` 后必须等待该 MCP 返回,再进行任何 Read/Grep/Glob/Bash/Write/Edit;不要并发发起上下文请求和直接工具调用。
|
|
65
67
|
- 每次写操作后读取返回状态;状态不明确或发生 stale turn 时调用 `mcp__devflow__delivery_status`。
|
|
66
68
|
- 只执行当前 `nextActions` 允许的操作。
|
|
67
69
|
- 澄清与设计交互使用当前 turn;后续写操作携带案件当前 context receipt。
|
|
68
70
|
- 只有用户明确同意时才能调用 `mcp__devflow__delivery_approve`;不得代替用户批准。
|
|
71
|
+
- 审批返回后不要结束会话:立即读取同一次返回的 `stage` 和 `nextActions`,按其允许的下一步继续推进;只有 `nextActions` 为空或用户明确暂停时才结束。
|
|
69
72
|
- `mcp__devflow__delivery_advance` 用于推进已满足的状态,`mcp__devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
|
|
70
73
|
- 失败任务只通过 `mcp__devflow__delivery_retry_task` 重试;取消和导出分别使用 `mcp__devflow__delivery_cancel` 与 `mcp__devflow__delivery_export`。
|
|
71
74
|
- Claude 在当前工作区产生的修改不是 Delivery 输出;只能先调用 `mcp__devflow__delivery_import_external_change`,由系统校验 base/candidate、允许文件、context receipt 和验证证据后再进入 integration。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.16",
|
|
4
4
|
"description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.18.
|
|
16
|
-
"@devflow-tools/context-engine": "0.18.
|
|
17
|
-
"@devflow-tools/database": "0.18.
|
|
18
|
-
"@devflow-tools/mcp-server": "0.18.
|
|
19
|
-
"@devflow-tools/memory-engine": "0.18.
|
|
20
|
-
"@devflow-tools/sdk": "0.18.
|
|
21
|
-
"@devflow-tools/semantic-engine": "0.18.
|
|
22
|
-
"@devflow-tools/server": "0.18.
|
|
23
|
-
"@devflow-tools/task-runtime": "0.18.
|
|
24
|
-
"@devflow-tools/telemetry": "0.18.
|
|
25
|
-
"@devflow-tools/workflow-engine": "0.18.
|
|
15
|
+
"@devflow-tools/benchmark": "0.18.16",
|
|
16
|
+
"@devflow-tools/context-engine": "0.18.16",
|
|
17
|
+
"@devflow-tools/database": "0.18.16",
|
|
18
|
+
"@devflow-tools/mcp-server": "0.18.16",
|
|
19
|
+
"@devflow-tools/memory-engine": "0.18.16",
|
|
20
|
+
"@devflow-tools/sdk": "0.18.16",
|
|
21
|
+
"@devflow-tools/semantic-engine": "0.18.16",
|
|
22
|
+
"@devflow-tools/server": "0.18.16",
|
|
23
|
+
"@devflow-tools/task-runtime": "0.18.16",
|
|
24
|
+
"@devflow-tools/telemetry": "0.18.16",
|
|
25
|
+
"@devflow-tools/workflow-engine": "0.18.16"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@devflow-tools/devflow": "0.18.
|
|
28
|
+
"@devflow-tools/devflow": "0.18.16"
|
|
29
29
|
},
|
|
30
30
|
"allowScripts": {
|
|
31
31
|
"better-sqlite3@12.11.1": true,
|
|
@@ -10,13 +10,16 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
|
|
|
10
10
|
## 开始案件
|
|
11
11
|
|
|
12
12
|
收到新的交付需求时,调用 `mcp__devflow__delivery_create_case`。使用当前项目绝对路径;默认 `baseRef=HEAD`、`targetRef=main`,除非用户明确指定其他值。为 actor、session、execution 和每次写操作生成稳定且可追踪的标识与幂等键。
|
|
13
|
+
- 若上下文检索发现同名组件、同一路由或多个框架实现,将候选路径通过 `existingImplementations` 传入创建案件参数,让案件先进入阻塞澄清;不要自行选择复用或替换。
|
|
13
14
|
|
|
14
15
|
## 推进规则
|
|
15
16
|
|
|
17
|
+
- 调用 `mcp__devflow__get_project_context` 后必须等待该 MCP 返回,再进行任何 Read/Grep/Glob/Bash/Write/Edit;不要并发发起上下文请求和直接工具调用。
|
|
16
18
|
- 每次写操作后读取返回状态;状态不明确或发生 stale turn 时调用 `mcp__devflow__delivery_status`。
|
|
17
19
|
- 只执行当前 `nextActions` 允许的操作。
|
|
18
20
|
- 澄清与设计交互使用当前 turn;后续写操作携带案件当前 context receipt。
|
|
19
21
|
- 只有用户明确同意时才能调用 `mcp__devflow__delivery_approve`;不得代替用户批准。
|
|
22
|
+
- 审批返回后不要结束会话:立即读取同一次返回的 `stage` 和 `nextActions`,按其允许的下一步继续推进;只有 `nextActions` 为空或用户明确暂停时才结束。
|
|
20
23
|
- `mcp__devflow__delivery_advance` 用于推进已满足的状态,`mcp__devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
|
|
21
24
|
- 失败任务只通过 `mcp__devflow__delivery_retry_task` 重试;取消和导出分别使用 `mcp__devflow__delivery_cancel` 与 `mcp__devflow__delivery_export`。
|
|
22
25
|
- Claude 在当前工作区产生的修改不是 Delivery 输出;只能先调用 `mcp__devflow__delivery_import_external_change`,由系统校验 base/candidate、允许文件、context receipt 和验证证据后再进入 integration。
|