@devflow-tools/claude-code-plugin 0.19.9 → 0.19.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/command-registry.json +7 -7
- package/dist/hooks/hook-daemon.js +24 -24
- package/dist/hooks/pre-tool-use.js +1 -1
- package/dist/hooks/stop.js +6 -6
- package/dist/hooks/user-prompt-submit.js +11 -11
- package/dist/runtime-manifest.json +7 -7
- package/package.json +14 -14
- package/skills/devflow:delivery/SKILL.md +21 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import {getLocalApiKey,getDevFlowStateRoot,resolveProjectCapabilityProfile,resolveCapabilityRollout,parseTrustedDecisionCommand,claudeCodeRuntimeAdapter,semanticTextHash,stableRuntimeHash,resolveRuntimeActivationSnapshot,getProjectStateDir,domainHash,encodeDecisionValue,canonicalJsonBytes,projectClaudeToolName,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 as randomUUID$1,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 {randomUUID,createHash as createHash$1,generateKeyPairSync,sign}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {createTrustedDeliveryFacade}from'@devflow-tools/mcp-server/trusted-delivery-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 B="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function W(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Ge(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(Ge(n))}function Z(n){return Buffer.from(n,"utf8").toString("base64url")}function Qe(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$1().slice(0,8)}`}function oe(n){return `${n}:legacy-journal`}var x=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let r=this.get(t);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==t)&&(o.executionId=`exec_${Date.now()}_${randomUUID$1().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=Q(i.evidenceObligations),i.evidenceDegradations=ee(i.evidenceDegradations),i.evidenceOutcomes=te(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),c=(o?void 0:i.evidenceObligations.find(m=>m.contractId===t.id))?.obligationId??Qe(t.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:c,contractId:t.id,at:r,contract:t},`add\0${c}`),this.replayEvidenceJournal(i);let l=i.evidenceObligations.find(m=>m.obligationId===c);return l?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(l)):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),c=s?.evidenceObligations.find(a=>a.obligationId===t);if(!s||!c)return null;let l=/^[a-f0-9]{64}$/.test(o)?o:"";if(!l)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:c.contractId,at:i,fingerprint:l,violations:r.slice(0,16).map(a=>a.slice(0,240))},`correction\0${t}\0${l}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let m=s.evidenceObligations.find(a=>a.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(l=>l.obligationId===t);if(!i||!s)return false;let c=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:o,reason:c},`degrade\0${t}\0${c}`),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,`${Z(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",Z(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 c=join$1(o,`.${process.pid}.${randomUUID$1()}.tmp`);writeFileSync(c,JSON.stringify(t),{mode:384});try{linkSync(c,s);}catch(l){if(l.code!=="EEXIST")throw l}finally{rmSync(c,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=Q(e.evidenceObligations),e.evidenceDegradations=ee(e.evidenceDegradations),e.evidenceOutcomes=te(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 c=et(JSON.parse(s));return c?[c]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||ne(i.kind)-ne(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(c=>c.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$1()}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384}),renameSync(r,t);}};function Q(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)||!ie(t.contract))return [];let r=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:oe(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 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"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function te(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 et(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:oe(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return ie(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 ne(n){return n==="add"?0:n==="correction"?1:2}function ie(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 tt(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 se(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=tt(e[1]);return t?{rawName:e[1],skillName:t}:null}var p=emitSemanticControlLog;var at=2,ct=1;function dt(){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 ae(n=dt()){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!==at&&r.version!==ct||!lt(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 lt(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 D(t.mcpTools)&&D(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||D(t.runtimePackages))&&(t.hostTools===void 0||ut(t.hostTools))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function ut(n){return !!n&&typeof n=="object"&&!Array.isArray(n)&&Object.entries(n).every(([e,t])=>e.length>0&&D(t))}function D(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}var yt={react:["react","react-dom"],nextjs:["next","react"],vue:["vue"],nest:["@nestjs/core"],tailwind:["tailwindcss"],taro:["@tarojs/taro"],electron:["electron"],graphql:["graphql"]};function ht(n,e){let t=join(n,"package.json"),r=ue(t),o=St(r,e),i=join(n,"package-lock.json"),s=ue(i),c=Rt(s,e);return c?{packageName:e,...o?{declaredRange:o}:{},resolvedVersion:c,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 me(n,e,t={}){let r=n.replace(/^devflow:/,"").split(":").pop()??n,o=(yt[r]??[]).map(c=>ht(e,c)),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 l=s.listLearningCandidates({projectRoot:e,states:["shadow","evaluated","active"],limit:100}).filter(d=>d.projectRoot===e||d.scope==="global").filter(d=>!d.expiresAt||d.expiresAt>(t.now??Date.now())).filter(d=>bt(d,n,t)).sort((d,f)=>f.confidence-d.confidence||f.updatedAt-d.updatedAt),m=It(l.map(d=>vt(d,d.state==="active"?"active":"shadow")),t),a=i==="on"?m.filter(d=>d.state==="active"):[],u=m.filter(d=>d.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(d=>`${d.candidateId}@${d.version}`),injected:a.map(d=>`${d.candidateId}@${d.version}`)}});}catch{}return {skillName:n,projectRoot:e,packages:o,learned:a,shadowEligible:u,rolloutMode:i}}finally{t.database||s.close();}}function pe(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,parseTrustedDecisionCommand,claudeCodeRuntimeAdapter,semanticTextHash,stableRuntimeHash,resolveRuntimeActivationSnapshot,getProjectStateDir,domainHash,encodeDecisionValue,canonicalJsonBytes,projectClaudeToolName,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 as randomUUID$1,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 {randomUUID,createHash as createHash$1,generateKeyPairSync,sign}from'node:crypto';import {DatabaseSync}from'node:sqlite';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {createTrustedDeliveryFacade}from'@devflow-tools/mcp-server/trusted-delivery-runtime';function h(t,e,n){try{let r=openGlobalDevFlowDatabase();try{r.insertEvent({kind:t,timestamp:Date.now(),duration:n,success:e.success!==!1,metadata:e});}finally{r.close();}}catch{}}var B="WARNING: DevFlow is in degraded mode (daemon unreachable): 4-Gate enforcement and memory prefetch cache are unavailable. Run `devflow doctor` for details.";function W(){return process.env.DEVFLOW_HOOK_DEGRADED==="1"}function Ge(t){return t??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(t){return getProjectStateDir(Ge(t))}function Z(t){return Buffer.from(t,"utf8").toString("base64url")}function Qe(t,e,n){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 `${t}:${o}`}return `${t}:legacy-${n}-${randomUUID$1().slice(0,8)}`}function oe(t){return `${t}:legacy-journal`}var x=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let n=e.trim();if(!n)throw new Error("session_id_required");let r=this.get(n);if(r)return r.lastActivityAt=Date.now(),this.persist(r),r;let o=Date.now(),i={sessionId:n,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:o,lastActivityAt:o};return this.sessions.set(n,i),this.persist(i),i}startExecution(e,n,r){let o=this.registerSession(e);return (!o.executionId||o.skillName!==n)&&(o.executionId=`exec_${Date.now()}_${randomUUID$1().slice(0,8)}`),o.skillName=n,o.requiredMcpTools=[...new Set(r)],delete o.contextInitialization,o.lastActivityAt=Date.now(),this.persist(o),o}beginContextInitialization(e,n){let r=this.registerSession(e);return r.contextInitialization={startedAt:Date.now(),...n?{toolUseId:n}:{}},r.lastActivityAt=Date.now(),this.persist(r),r}completeContextInitialization(e,n){let r=this.get(e);return r?(n&&r.contextInitialization?.toolUseId&&r.contextInitialization.toolUseId!==n||(delete r.contextInitialization,r.lastActivityAt=Date.now(),this.persist(r)),r):null}bindTaskIdentity(e,n){let r=this.registerSession(e);return r.activeTurnId=n.turnId,r.activeRequestId=n.requestId,r.intentArtifactHash=n.intentArtifactHash,r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let n=e.trim();if(!n)return null;let r=this.sessions.get(n);if(r)return this.replayEvidenceJournal(r),r;let o=this.snapshotPath(n);if(!existsSync(o))return null;try{let i=JSON.parse(readFileSync$1(o,"utf8"));return i.sessionId!==n||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=Q(i.evidenceObligations),i.evidenceDegradations=ee(i.evidenceDegradations),i.evidenceOutcomes=te(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(n,i),i)}catch{return null}}completeExecution(e){let n=this.get(e);if(!n)return null;let r=structuredClone(n);return delete n.executionId,delete n.skillName,delete n.contextInitialization,n.requiredMcpTools=[],n.lastActivityAt=Date.now(),this.persist(n),r}addEvidenceObligation(e,n,r=Date.now(),o){let i=this.registerSession(e),a=(o?void 0:i.evidenceObligations.find(m=>m.contractId===n.id))?.obligationId??Qe(n.id,o,r);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:n.id,at:r,contract:n},`add\0${a}`),this.replayEvidenceJournal(i);let l=i.evidenceObligations.find(m=>m.obligationId===a);return l?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(l)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(n=>structuredClone(n))}markEvidenceCorrection(e,n,r,o,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(c=>c.obligationId===n);if(!s||!a)return null;let l=/^[a-f0-9]{64}$/.test(o)?o:"";if(!l)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:n,contractId:a.contractId,at:i,fingerprint:l,violations:r.slice(0,16).map(c=>c.slice(0,240))},`correction\0${n}\0${l}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let m=s.evidenceObligations.find(c=>c.obligationId===n);return m?structuredClone(m):null}resolveEvidenceObligation(e,n){let r=this.get(e);if(!r)return false;let o=r.evidenceObligations.find(s=>s.obligationId===n);if(!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:n,contractId:o.contractId,at:i},`resolve\0${n}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}resolveDegradedEvidence(e,n){let r=this.get(e),o=r?.evidenceDegradations.find(s=>s.obligationId===n);if(!r||!o)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:n,contractId:o.contractId,at:i},`resolve-degraded\0${n}\0${i}`),this.replayEvidenceJournal(r),r.lastActivityAt=i,this.persist(r),true}degradeEvidenceObligation(e,n,r,o=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(l=>l.obligationId===n);if(!i||!s)return false;let a=r.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:n,contractId:s.contractId,at:o,reason:a},`degrade\0${n}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=o,this.persist(i),true}removeSession(e){let n=e.trim();n&&(this.sessions.delete(n),rmSync(this.snapshotPath(n),{force:true}),rmSync(this.evidenceJournalDir(n),{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,n,r){let o=this.evidenceJournalDir(e);mkdirSync(o,{recursive:true,mode:448});let i=createHash("sha256").update(r).digest("hex"),s=join$1(o,`${n.kind}-${i}.json`);if(existsSync(s))return;let a=join$1(o,`.${process.pid}.${randomUUID$1()}.tmp`);writeFileSync(a,JSON.stringify(n),{mode:384});try{linkSync(a,s);}catch(l){if(l.code!=="EEXIST")throw l}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=Q(e.evidenceObligations),e.evidenceDegradations=ee(e.evidenceDegradations),e.evidenceOutcomes=te(e.evidenceOutcomes);let n=this.evidenceJournalDir(e.sessionId);if(!existsSync(n))return;let r;try{r=readdirSync(n).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(n,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=et(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||ne(i.kind)-ne(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,n){let r=e.evidenceOutcomes.find(s=>s.obligationId===n.obligationId);if(n.kind==="add"){if(r)return;let s=e.evidenceObligations.find(a=>a.obligationId===n.obligationId);s?(s.contract=n.contract,s.promptedAt=Math.min(s.promptedAt,n.at)):e.evidenceObligations.push({obligationId:n.obligationId,contractId:n.contractId,contract:n.contract,promptedAt:n.at,attempt:0,correctionRequested:false,violations:[]});return}let o=e.evidenceObligations.find(s=>s.obligationId===n.obligationId);if(n.kind==="correction"){if(!o||r||o.correctionFingerprint===n.fingerprint)return;o.attempt+=1,o.correctionRequested=true,o.correctionRequestedAt=n.at,o.correctionFingerprint=n.fingerprint,o.violations=n.violations;return}let i=o?.attempt??r?.attempt??0;if(n.kind==="resolve"&&r?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==n.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==n.obligationId);else if(r)return;n.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==n.obligationId),e.evidenceDegradations.push({obligationId:n.obligationId,contractId:n.contractId,reason:n.reason,degradedAt:n.at,attempt:i,contract:o?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==n.obligationId),e.evidenceOutcomes.push({obligationId:n.obligationId,contractId:n.contractId,status:n.kind==="resolve"?"resolved":"degraded",completedAt:n.at,attempt:i,...n.kind==="degrade"?{reason:n.reason}:{}});}persist(e){mkdirSync(this.sessionsDir,{recursive:true,mode:448});let n=this.snapshotPath(e.sessionId),r=`${n}.${process.pid}.${randomUUID$1()}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384}),renameSync(r,n);}};function Q(t){return Array.isArray(t)?t.flatMap(e=>{if(!e||typeof e!="object")return [];let n=e;if(typeof n.contractId!="string"||n.contractId.length===0||n.contractId.length>128||typeof n.promptedAt!="number"||typeof n.attempt!="number"||typeof n.correctionRequested!="boolean"||!Array.isArray(n.violations)||!ie(n.contract))return [];let r=typeof n.obligationId=="string"&&n.obligationId.length>0&&n.obligationId.length<=384?n.obligationId:oe(n.contractId),o=typeof n.correctionTranscriptHash=="string"?n.correctionTranscriptHash:void 0,i=n.correctionFingerprint??o;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...n,obligationId:r,correctionFingerprint:i}]}).slice(-8):[]}function ee(t){return Array.isArray(t)?t.filter(e=>{if(!e||typeof e!="object")return false;let n=e;return typeof n.obligationId=="string"&&typeof n.contractId=="string"&&typeof n.reason=="string"&&typeof n.degradedAt=="number"&&typeof n.attempt=="number"}).slice(-20):[]}function te(t){return Array.isArray(t)?t.filter(e=>{if(!e||typeof e!="object")return false;let n=e;return typeof n.obligationId=="string"&&typeof n.contractId=="string"&&(n.status==="resolved"||n.status==="degraded")&&typeof n.completedAt=="number"&&typeof n.attempt=="number"&&(n.reason===void 0||typeof n.reason=="string")}).slice(-20):[]}function et(t){if(!t||typeof t!="object")return null;let e=t,n=e.kind;if(n!=="add"&&n!=="correction"&&n!=="resolve"&&n!=="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:oe(e.contractId),contractId:e.contractId,at:e.at};if(n==="add")return ie(e.contract)?{kind:n,...o,contract:e.contract}:null;if(n==="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:n,...o,fingerprint:i,violations:e.violations}:null}return n==="resolve"?{kind:n,...o}:typeof e.reason=="string"&&e.reason.length<=240?{kind:n,...o,reason:e.reason}:null}function ne(t){return t==="add"?0:t==="correction"?1:2}function ie(t){if(!t||typeof t!="object")return false;let e=t,n=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(n)&&n.length===3&&n[0]==="\u5DE5\u5177\u53D1\u73B0"&&n[1]==="\u6A21\u578B\u5047\u8BBE"&&n[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 tt(t){let e=t.trim().replace(/^\//,"");if(!e.startsWith("devflow:"))return null;let n=e.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(n)?`devflow:${n.toLowerCase()}`:null}function se(t){let e=t.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let n=tt(e[1]);return n?{rawName:e[1],skillName:n}:null}var f=emitSemanticControlLog;var at=2,ct=1;function dt(){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 ae(t=dt()){let e=[join$1(t,"dist","command-registry.json"),join$1(t,"command-registry.json")];for(let n of e)try{if(!existsSync(n))continue;let r=JSON.parse(readFileSync$1(n,"utf8"));if(r.version!==at&&r.version!==ct||!lt(r.commands)){f({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:n}});continue}return r.commands}catch(r){f({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 lt(t){return !t||typeof t!="object"||Array.isArray(t)?false:Object.values(t).every(e=>{if(!e||typeof e!="object"||Array.isArray(e))return false;let n=e;return D(n.mcpTools)&&D(n.blockedNative)&&(n.source===void 0||n.source==="core"||n.source==="plugin")&&(n.requiresContext===void 0||typeof n.requiresContext=="boolean")&&(n.runtimePackages===void 0||D(n.runtimePackages))&&(n.hostTools===void 0||ut(n.hostTools))&&(n.evidenceMode===void 0||["static","runtime","mixed"].includes(n.evidenceMode))})}function ut(t){return !!t&&typeof t=="object"&&!Array.isArray(t)&&Object.entries(t).every(([e,n])=>e.length>0&&D(n))}function D(t){return Array.isArray(t)&&t.every(e=>typeof e=="string"&&e.length>0)}var yt={react:["react","react-dom"],nextjs:["next","react"],vue:["vue"],nest:["@nestjs/core"],tailwind:["tailwindcss"],taro:["@tarojs/taro"],electron:["electron"],graphql:["graphql"]};function ht(t,e){let n=join(t,"package.json"),r=ue(n),o=St(r,e),i=join(t,"package-lock.json"),s=ue(i),a=Rt(s,e);return a?{packageName:e,...o?{declaredRange:o}:{},resolvedVersion:a,evidencePath:relative(t,i)||"package-lock.json",confidence:"high"}:o?{packageName:e,declaredRange:o,evidencePath:relative(t,n)||"package.json",confidence:"medium"}:{packageName:e,confidence:"unknown"}}function me(t,e,n={}){let r=t.replace(/^devflow:/,"").split(":").pop()??t,o=(yt[r]??[]).map(a=>ht(e,a)),i=n.rolloutMode??resolveCapabilityRollout(e).config.learningOverlays;if(i==="off")return {skillName:t,projectRoot:e,packages:o,learned:[],shadowEligible:[],rolloutMode:i};let s=n.database??openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let l=s.listLearningCandidates({projectRoot:e,states:["shadow","evaluated","active"],limit:100}).filter(d=>d.projectRoot===e||d.scope==="global").filter(d=>!d.expiresAt||d.expiresAt>(n.now??Date.now())).filter(d=>bt(d,t,n)).sort((d,p)=>p.confidence-d.confidence||p.updatedAt-d.updatedAt),m=It(l.map(d=>vt(d,d.state==="active"?"active":"shadow")),n),c=i==="on"?m.filter(d=>d.state==="active"):[],u=m.filter(d=>d.state==="shadow"||i==="shadow");try{s.insertEvent({kind:"learning_overlay_match",timestamp:Date.now(),success:!0,metadata:{projectRoot:e,skillName:t,rolloutMode:i,eligible:m.map(d=>`${d.candidateId}@${d.version}`),injected:c.map(d=>`${d.candidateId}@${d.version}`)}});}catch{}return {skillName:t,projectRoot:e,packages:o,learned:c,shadowEligible:u,rolloutMode:i}}finally{n.database||s.close();}}function pe(t){let e=[],n=t.packages.map(r=>{let o=r.resolvedVersion??r.declaredRange??"unknown";return `${r.packageName}=${o} (confidence=${r.confidence}${r.evidencePath?`, source=${r.evidencePath}`:""})`}).join("; ");return n&&e.push(`DevFlow runtime project-version evidence for ${t.skillName}: ${n}. Treat target-project evidence as authoritative; do not apply a hardcoded framework version.`),t.learned.length>0&&e.push([`DevFlow governed project instructions for ${t.skillName}:`,...t.learned.map(r=>`- ${r.instruction}`),"Apply only to this request and keep canonical Skill/MCP requirements unchanged."].join(`
|
|
2
2
|
`)),e.join(`
|
|
3
|
-
`)}function vt(
|
|
4
|
-
`;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(r)}),appendFileSync(t,r);}catch{}}function Nt(n){return new Promise(e=>setTimeout(e,n))}var ke=1e4,Vt=3e4,T=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 c={executionId:e,sessionId:t,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",c)&&this.postHttp("/api/telemetry/skill-execution/start",c);}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:T}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),t.resolveTelemetryFailure(o.id);}catch{}t.trimTelemetryFailures(T);}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:zt(JSON.parse(readFileSync$1(r,"utf8")))}}catch{return null}}).filter(t=>t!==null).sort((t,r)=>t.envelope.timestamp-r.envelope.timestamp||Se(t.envelope.operation)-Se(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:Re(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(Re(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(T),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-T)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Vt).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){ve(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 Se(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Re(n){return `hook-run:${n}`}function zt(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 Bt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Wt=/\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,Gt=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Yt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function k(n){let e=n.trim().replace(Bt,"").trim();return !e||Wt.test(e)?null:(Yt.exec(e)??Gt.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var M=1,rn="memory-snapshot-v1.json",on=512*1024,Ee=256*1024,Ae=2e3,sn=500,an=10,cn=240,dn=300*1e3,ln=720*60*60*1e3,un=2147483647;function mn(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 pn(n,e={}){let t=S(n),r=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(I(n));return join(r,rn)}function fn(n,e){let r=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function L(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function gn(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 yn(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 Te(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!==M||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>Ee||!L(r.memoryIds,Ae)||!Array.isArray(r.conflicts)||r.conflicts.length>sn||!r.conflicts.every(gn)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>t+dn||!Number.isInteger(s)||s<0||s>un||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!yn(r.degradation)?null:{...r,generation:s}}function hn(n,e,t,r,o=0){let i=I(n);return {version:M,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:t}}}function vn(n,e={}){let t=e.now??Date.now(),r=pn(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>on)throw new Error("cache_size_invalid");let s=mn({...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 c=JSON.parse(readFileSync(o,"utf8")),l=Te(c,n,t);if(!l)throw new Error("cache_schema_invalid");return l.status==="ready"&&t-l.generatedAt>ln?{snapshot:{...l,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:l,source:"cache",valid:!0,stale:!1}}catch(i){let c=i.code==="ENOENT";return {snapshot:hn(n,c?"pending":"degraded",c?"cache_missing":fn(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function In(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function bn(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:M,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let o=Te(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:M,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:L(r.memoryIds,Ae)?r.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function N(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,cn).join("")}function wn(n){if(n.length===0)return "";let e=n.slice(0,an),t=e.map(r=>{let o=N(r.family,"unknown"),i=N(r.entity,"unknown"),s=N(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
5
|
-
${
|
|
6
|
-
`)}`}function kn(
|
|
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}`:"",
|
|
8
|
-
`):["## Project memory",l,`${
|
|
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(kn({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=Dn(e.kind,e.payload??{});if(!t)return {handled:false};let r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=xn(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 xn(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(l=>r?l.turnId===r:l.requestId===o);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let c=n.getTaskDefinitionV2(s.taskDefinitionHash);return !c||c.revision!==i.version?null:{definition:c,snapshot:s}}function Dn(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 An=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,Tn=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,Cn=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,Mn=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function On(n){let e=n.trim();return e.length>0&&!An.test(e)}function jn(n){let e=n.normalize("NFKC").trim(),t=Mn.test(e);return e.length>=4&&(Cn.test(e)||t)&&(!Tn.test(e)||t)&&k(e)===null}function $n(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 Me(n,e,t=[]){return `memory-receipt:${createHash$1("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Pn(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function 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(c=>c.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 ${projectClaudeToolName("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 Oe(n){if(!On(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??$n(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 l=(n.activation?.semantic??"degraded_structural")==="degraded_structural"?k(t)??void 0:void 0;if(!l&&jn(t)){let u=Me(s.turnId,"skipped"),d=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:d,additionalContext:U(d),skipSkillRouting:!1}}let m=l?"commit_explicit":"capture_prompt",a=e.enqueueWork({idempotencyKey:`memory-turn:${m}:${s.turnId}`,kind:l?"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:l,createdAt:s.createdAt}});if(l){let u=`raw-memory:${createHash$1("sha256").update(`${n.projectRoot}\0${i.turnId}\0${l}`).digest("hex").slice(0,24)}`,d=Me(s.turnId,"committed",[u]),f=e.commitMemoryTurn({turnId:s.turnId,receiptId:d,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:a.id,obligation:"memory"},dedupeKey:`${a.id}:owned`,producer:"devflow-memory-turn"}),b({projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:d,reasonCode:"explicit_raw_queued"},dedupeKey:d,producer:"devflow-memory-turn"}),p({event:"memory.write.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,actionReceipt:d},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:u,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:f,explicitContent:l,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:a.id,obligation:"memory"},dedupeKey:`${a.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:l,additionalContext:Pn(s),skipSkillRouting:!1}}finally{e.close();}}function $e(n,e){let t=qn(n);mkdirSync$1(t,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID()}`,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 qn(n){return join(w(n),"memory-turn-pending")}function Pe(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${Jn(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 Jn(n){return n.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}async function Le(n){let e=Date.now(),t=rr(n.projectRoot),r=claudeCodeRuntimeAdapter.normalizePrompt(n.hostEvent??{session_id:n.sessionId,prompt:n.prompt},{projectRoot:t}),o=semanticTextHash(Ne(r.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:t,sessionId:n.sessionId,sourceHash:o});if(s){let j=Fe(s).identity,z=i.getRuntimeActivation(j.projectRoot,j.sessionId,j.turnId,s.version);if(!z)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:Fe(s),memoryIdentity:He(s),activation:z,reused:!0}}let c=`turn:${O(`${n.sessionId}\0${o}`)}`,l=`request:${O(`${t}\0${n.sessionId}\0${c}`)}`,m={projectRoot:t,projectId:`project:${stableRuntimeHash(t).slice(0,20)}`,hostId:r.hostId,sessionId:n.sessionId,executionId:n.sessionId,turnId:c,requestId:l},a=1,u=resolveRuntimeActivationSnapshot({projectRoot:t,createdAt:r.timestamp}),d=tr(r.rawPrompt),f={identity:m,version:a,rawPrompt:r.rawPrompt,normalizedPrompt:Ne(r.rawPrompt),...r.command?{command:r.command}:{},slashArgs:r.slashArgs,...r.activeSkill?{activeSkill:r.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:d,policyConstraints:[],classificationEvidence:[],sourceEventIds:[r.sourceEventId??`host-event:${o.slice(0,24)}`],sourceHash:o,createdAt:r.timestamp},y={...f,artifactHash:or(f)};i.appendTaskIntentArtifact(Qn(y)),i.bindRuntimeActivation({identity:m,revision:a,snapshot:u});let ze=Zn(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:d.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:ze,sourceIntentHash:y.artifactHash}}),{artifact:y,memoryIdentity:He(y),activation:u,reused:!1}}finally{i.close();}}function Zn(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 Qn(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 Fe(n){return {identity:er(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 er(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 He(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 tr(n){let e=n.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return nr(e.map(t=>t.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(t=>!t.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(t))).slice(0,16)}function Ne(n){return n.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function nr(n){return [...new Set(n.filter(Boolean))]}function rr(n){let e=resolve(n);try{return realpathSync(e)}catch{return e}}function or(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(",")}}`}function Ue(){return generateKeyPairSync("ed25519")}function Ke(n){let e=parseTrustedDecisionCommand(n.rawUserEvent,n.allowedOptionIds),t=n.now??Date.now(),r={schemaVersion:"delivery-user-attestation.v1",issuer:n.issuer,keyId:n.keyId,purpose:e.purpose,decisionId:e.decisionId,caseId:n.caseId,caseVersion:n.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId,actorId:n.actorId,targetDecisionHash:n.targetDecisionHash,rawUserEvent:n.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",n.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:e.decisionId,purpose:e.purpose,value:encodeDecisionValue(e.purpose,e.value)}),eventSequence:n.eventSequence,issuedAt:new Date(t).toISOString(),expiresAt:new Date(t+6e4).toISOString(),nonce:n.nonce};return {...r,attestation:sign(null,canonicalJsonBytes(r),n.privateKey).toString("base64url")}}var Je=new Map;async function Ve(n){let e=n.prompt.trim();if(!/^\/devflow:(?:decide|approve|reject|revise|cancel|exit)\b/u.test(e))return {handled:false};let t=pr(n.projectRoot),r=e;if(e==="/devflow:approve"||e==="/devflow:approve current"){let a=await t.pendingDecisionForSession(n.sessionId);if(!a)return {handled:true,resolved:false,message:"DevFlow approval not found: there is no pending decision for this session."};if("ambiguous"in a)return {handled:true,resolved:false,message:`DevFlow approval is ambiguous: multiple pending cases exist (${a.caseIds.join(", ")}). Use the approval choices shown by the host.`};if(a.decision.kind!=="artifact_approval")return {handled:true,resolved:false,message:"DevFlow approval is not available yet: the current pending item is a clarification, not an artifact gate."};r=`/devflow:approve ${a.decision.id}`;}let o;try{o=parseTrustedDecisionCommand(r);}catch(a){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${a instanceof Error?a.message:String(a)}`}}let i=o.decisionId.split(/:(?:decision|question|approval):/u)[0],s=await t.pendingDecision(i);if(!s||s.id!==o.decisionId)return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: no pending decision matches ${o.decisionId}. Refresh delivery_status.`};let c=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,l=Ue(),m=Ke({rawUserEvent:r,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:n.sessionId,sourceTurnId:n.sourceTurnId?.trim()||`host-turn:${n.sessionId}:${Date.now()}`,actorId:c,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID(),privateKey:l.privateKey,allowedOptionIds:s.options.map(a=>a.id)});try{return await t.resolveTrustedDecision({evidence:m,publicKey:l.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow trusted decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(a){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${a instanceof Error?a.message:String(a)}`}}}function pr(n){let e=Je.get(n);if(e)return e;let t=createTrustedDeliveryFacade(n);return Je.set(n,t),t}var g=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function yr(n){let e=W()?[B]:[],t;try{t=JSON.parse(n);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
10
|
-
`)}:{}}}}let r=
|
|
11
|
-
`)}:{}}};let o=
|
|
12
|
-
`)}:{}}}}if(process.argv[1]?.endsWith("user-prompt-submit")||process.argv[1]?.endsWith("user-prompt-submit.js")){let
|
|
3
|
+
`)}function vt(t,e){return {candidateId:t.id,version:t.overlayVersion,state:e,instruction:t.instruction,trigger:t.trigger,confidence:t.confidence,evidenceReceipt:t.graderReceipt??`candidate:${t.id}:v${t.overlayVersion}`,expiresAt:t.expiresAt}}function It(t,e){let n=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 t){if(o.length>=n)break;let a=s.instruction.length+4;i+a>r||(o.push(s),i+=a);}return o}function bt(t,e,n){let r=t.trigger,o=e.replace(/^devflow:/,"").split(":").pop()??e,i=E(r.skills);if(i.length>0&&!i.some(d=>d===e||d===o||d.endsWith(`:${o}`)))return false;let s=(n.prompt??"").normalize("NFKC").toLocaleLowerCase("en-US"),a=(n.command??"").normalize("NFKC").toLocaleLowerCase("en-US"),l=[...n.files??[],...wt(n.prompt??"")].map(d=>d.replaceAll("\\","/").toLocaleLowerCase("en-US")),m=E(r.commands).map(le);if(m.length>0&&!m.some(d=>a.includes(d)||s.includes(d)))return false;let c=E(r.entities).map(le);if(c.length>0&&!c.some(d=>s.includes(d)||a.includes(d)))return false;let u=E(r.files).map(d=>d.replaceAll("\\","/").toLocaleLowerCase("en-US"));return !(u.length>0&&!u.some(d=>l.some(p=>kt(p,d))))}function wt(t){return t.match(/(?:^|\s)((?:src|app|apps|packages|plugins|lib|test|tests)\/[A-Za-z0-9_./@-]+)/gu)?.map(e=>e.trim())??[]}function kt(t,e){if(!e.includes("*"))return t===e||t.includes(e);let n=e.replace(/[.+?^${}()|[\]\\]/gu,"\\$&").replaceAll("*",".*");return new RegExp(`^${n}$`,"u").test(t)}function E(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"&&e.trim().length>0):[]}function le(t){return t.normalize("NFKC").trim().toLocaleLowerCase("en-US")}function ue(t){if(!existsSync$1(t))return null;try{let e=JSON.parse(readFileSync(t,"utf8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}function St(t,e){for(let n of ["dependencies","devDependencies","peerDependencies","optionalDependencies"]){let r=t?.[n];if(!r||typeof r!="object"||Array.isArray(r))continue;let o=r[e];if(typeof o=="string"&&o.trim())return o.trim()}}function Rt(t,e){let n=t?.packages;if(n&&typeof n=="object"&&!Array.isArray(n)){let o=n[`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=t?.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 fe(t){let e=ae();return e?e[t]?.mcpTools??[]:[]}function ge(t,e,n){return pe(me(t,e,{prompt:n}))}var Pt=getLocalApiKey(),N=join(getDevFlowStateRoot(),"errors");async function ve(t,e,n={}){let r=n.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Ft();if(!r)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let o=n.timeout??1500,i=n.durableMirror??true,s=n.maxRetries??(i?0:2),a=n.circuitBreaker??true,l=acquireRuntimeHttpCircuit(r,t);if(a&&!l.allowed)return {delivered:false,suppressed:true,fallbackReason:l.state.fallbackReason};let m;for(let u=0;u<=s;u+=1)try{return await Nt(r,t,e,o),a&®isterRuntimeHttpSuccess(r,t).transitioned&&h("http_circuit_transition",{endpoint:r,path:new URL(t,r).pathname,previous:l.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(d){m=d instanceof Error?d:new Error(String(d)),u<s&&await Ht(Math.min(100*2**u,1e3));}if(!m)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return ye(t,m),{delivered:false,suppressed:false,fallbackReason:m.message};let c=registerRuntimeHttpFailure(r,t,n.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return c.transitioned&&(ye(t,m),h("http_circuit_transition",{endpoint:r,path:new URL(t,r).pathname,previous:l.state.status,status:"open",failures:c.state.failures,openUntil:c.state.openUntil,fallbackReason:c.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:c.state.fallbackReason}}function Ft(){let t=readRuntimeState();return t?.status==="ready"&&t.dashboardAvailable?t.url:void 0}function Nt(t,e,n,r){return new Promise((o,i)=>{let s=JSON.stringify(n),a=new URL(e,t),l=false,m=u=>{l||(l=true,u?i(u):o());},c=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Pt,"Content-Length":Buffer.byteLength(s)},timeout:r},u=>{u.on("error",m),u.on("end",()=>{let d=u.statusCode??0;m(d>=200&&d<300?void 0:new Error(`HTTP ${d}`));}),u.resume();});c.on("error",m),c.on("timeout",()=>c.destroy(new Error(`HTTP mirror timed out after ${r}ms`))),c.write(s),c.end();})}function ye(t,e){try{existsSync$1(N)||mkdirSync$1(N,{recursive:!0});let n=join(N,"http-errors.log"),r=`${new Date().toISOString()} | ${t} | ${e.message}
|
|
4
|
+
`;rotateDiagnosticLogFile({path:n,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(r)}),appendFileSync(n,r);}catch{}}function Ht(t){return new Promise(e=>setTimeout(e,t))}var ke=1e4,Vt=3e4,T=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 n=e?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(n)&&n>=0?n:100;}async sendEvent(e){let n={...e,input:this.truncateInput(e.input)};return this.commitOrCache("tool_call",n)?(this.postHttp("/api/telemetry/tool-call",n),e.eventId):null}async sendExecutionStart(e,n,r,o,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:n,skillName:r,startedAt:o,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,n="completed",r=Date.now(),o){let i={executionId:e,status:n,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,n,r){let o={id:e,projectRoot:n,startedAt:r,label:n.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",o);return i&&this.postHttp("/api/telemetry/sessions",o),i}async completeEvent(e){let n=this.commitOrCache("complete_event",e);return n&&(this.postHttp("/api/telemetry/tool-call/output",e),this.scheduleMetricAggregation()),n}async endSession(e,n=Date.now()){let r={sessionId:e,finishedAt:n},o=this.commitOrCache("session_end",r);return o&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:n})),o}async flushCache(){try{let n=this.getDatabase(),r=n.listTelemetryFailures({unresolvedOnly:!0,limit:T}).reverse();for(let o of r)try{this.applyOperation(o.operation,o.payload),n.resolveTelemetryFailure(o.id);}catch{}n.trimTelemetryFailures(T);}catch{}let e=(existsSync(this.cacheDir)?readdirSync(this.cacheDir):[]).filter(n=>n.endsWith(".json")).map(n=>{let r=join$1(this.cacheDir,n);try{return {cacheFile:r,envelope:zt(JSON.parse(readFileSync$1(r,"utf8")))}}catch{return null}}).filter(n=>n!==null).sort((n,r)=>n.envelope.timestamp-r.envelope.timestamp||Se(n.envelope.operation)-Se(r.envelope.operation));for(let{cacheFile:n,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(n);}catch{}this.database?.aggregatePendingToolMetrics();}aggregateMetrics(){return this.getDatabase().aggregatePendingToolMetrics()}async flushAndAggregate(){await this.flushCache(),this.aggregateMetrics();}close(){this.ownsDatabase&&this.database?.close(),this.database=null;}getDatabase(){return this.database??=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:this.busyTimeoutMs}),this.database}commitOrCache(e,n){try{return this.applyOperation(e,n),!0}catch(r){return this.cacheOperation(e,n,r),false}}applyOperation(e,n){let r=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(r,n),r.insertToolCallEvent(n);return;case "execution_start":this.ensureParentSession(r,n),r.insertSkillExecution({executionId:n.executionId,sessionId:n.sessionId,skillName:n.skillName,startedAt:n.startedAt,status:"running",requiredMcpTools:n.requiredMcpTools});return;case "execution_complete":r.reconcileSkillExecution(n.executionId,n.status,n.finishedAt,n.metadata);return;case "session_start":r.ensureSession(n),r.insertRun({id:Re(n.id),source:"hook",tool:"session",input:{projectRoot:n.projectRoot},status:"active",startedAt:n.startedAt,tokenUsed:0,metadata:{sessionId:n.id,projectRoot:n.projectRoot}});return;case "complete_event":if(!r.updateToolCallEvent(n.eventId,{output:n.output===void 0?void 0:JSON.stringify(n.output),error:n.error,failureCategory:n.failureCategory,duration:n.duration}))throw new Error(`Tool call event ${n.eventId} is not available for completion`);return;case "session_end":r.closeSession(n.sessionId,n.finishedAt),r.updateRun(Re(n.sessionId),{status:"completed",finishedAt:n.finishedAt});return}}ensureParentSession(e,n){let r=typeof n.sessionId=="string"?n.sessionId.trim():"";if(!r)throw new Error("Canonical session ID is required for telemetry");let o=typeof n.projectRoot=="string"&&n.projectRoot.trim()?n.projectRoot:typeof n.input?.projectRoot=="string"&&n.input.projectRoot.trim()?n.input.projectRoot:process.env.CLAUDE_PROJECT_DIR??"unknown";e.ensureSession({id:r,projectRoot:o,label:o==="unknown"?void 0:o.split("/").pop(),startedAt:Number(n.startedAt??n.timestamp??Date.now())});}cacheOperation(e,n,r){let o=Date.now(),i={id:`failure:${o}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:n,failure:r instanceof Error?r.message:String(r),timestamp:o};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:n,error:i.failure,createdAt:o}),s.trimTelemetryFailures(T),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(n=>n.endsWith(".json")).sort();for(let n of e.slice(0,Math.max(0,e.length-T)))unlinkSync(join$1(this.cacheDir,n));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Vt).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,n){ve(e,n,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let n=JSON.stringify(e);return n===void 0||n.length<=ke?e:{_truncated:true,_original_size:n.length,_preview:`${n.substring(0,ke)}...`}}};function Se(t){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(t)}function Re(t){return `hook-run:${t}`}function zt(t){if(!t||typeof t!="object")throw new Error("Invalid telemetry cache envelope");let e=t;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 Bt=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Wt=/\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,Gt=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Yt=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function k(t){let e=t.trim().replace(Bt,"").trim();return !e||Wt.test(e)?null:(Yt.exec(e)??Gt.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}var M=1,rn="memory-snapshot-v1.json",on=512*1024,Ee=256*1024,Ae=2e3,sn=500,an=10,cn=240,dn=300*1e3,ln=720*60*60*1e3,un=2147483647;function mn(t){return t.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:t.ownerUid===t.currentUid,modeSafe:(t.mode&18)===0}}function I(t){return resolve(t)}function S(t){return createHash$1("sha256").update(I(t)).digest("hex").slice(0,16)}function pn(t,e={}){let n=S(t),r=e.stateRoot?join(e.stateRoot,n):getProjectStateDir(I(t));return join(r,rn)}function fn(t,e){let r=(t instanceof Error?t.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return r?`${e}:${r}`:e}function L(t,e){return Array.isArray(t)&&t.length<=e&&t.every(n=>typeof n=="string"&&n.length>0&&n.length<=512)}function gn(t){if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;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 yn(t){if(!t||typeof t!="object"||Array.isArray(t))return false;let e=t;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function Te(t,e,n){if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t,o=I(e),i=S(o),s=r.generation===void 0?0:r.generation;return r.version!==M||r.projectRoot!==o||r.projectHash!==i||typeof r.markdown!="string"||Buffer.byteLength(r.markdown,"utf8")>Ee||!L(r.memoryIds,Ae)||!Array.isArray(r.conflicts)||r.conflicts.length>sn||!r.conflicts.every(gn)||typeof r.generatedAt!="number"||!Number.isFinite(r.generatedAt)||r.generatedAt<0||r.generatedAt>n+dn||!Number.isInteger(s)||s<0||s>un||!["ready","pending","degraded","disabled"].includes(String(r.status))||r.degradation!==void 0&&!yn(r.degradation)?null:{...r,generation:s}}function hn(t,e,n,r,o=0){let i=I(t);return {version:M,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:r,generation:o,status:e,degradation:{reason:n}}}function vn(t,e={}){let n=e.now??Date.now(),r=pn(t,e),o;try{o=openSync(r,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(o);if(!i.isFile()||i.size<=0||i.size>on)throw new Error("cache_size_invalid");let s=mn({...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")),l=Te(a,t,n);if(!l)throw new Error("cache_schema_invalid");return l.status==="ready"&&n-l.generatedAt>ln?{snapshot:{...l,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:l,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:hn(t,a?"pending":"degraded",a?"cache_missing":fn(i,"cache_invalid"),n),source:"none",valid:false,stale:false}}finally{if(o!==void 0)try{closeSync(o);}catch{}}}function In(t){if(!t)return true;try{return JSON.parse(readFileSync(t,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function bn(t,e,n){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(t);return {version:M,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:n,generation:0,status:"disabled"}}let o=Te(r.snapshot,t,n);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(t);return {version:M,projectRoot:i,projectHash:S(i),markdown:r.markdown,memoryIds:L(r.memoryIds,Ae)?r.memoryIds:[],conflicts:[],generatedAt:n,generation:0,status:"ready"}}}catch{}return null}function H(t,e){return [...(t??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,cn).join("")}function wn(t){if(t.length===0)return "";let e=t.slice(0,an),n=e.map(r=>{let o=H(r.family,"unknown"),i=H(r.entity,"unknown"),s=H(r.summary,"Explicit choice required.");return `- family=${o}; entity=${i}; status=${r.status}; summary=${s}`});return t.length>e.length&&n.push(`- ${t.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${t.length})
|
|
5
|
+
${n.join(`
|
|
6
|
+
`)}`}function kn(t){let e=t.now??Date.now();if(In(t.configPath)===false)return "";let n=bn(t.projectRoot,t.daemonResponse??"",e),r=n?{snapshot:n,source:"daemon"}:vn(t.projectRoot,{...t.cacheOptions,now:e}),{snapshot:o}=r;if(o.status==="disabled")return `## Project memory
|
|
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}.`,l=wn(o.conflicts);return o.markdown?[o.markdown,l,a].filter(Boolean).join(`
|
|
8
|
+
`):["## Project memory",l,`${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[,,t,e,n]=process.argv;t!=="session-start"||!e?process.exitCode=2:process.stdout.write(kn({projectRoot:e,configPath:n,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function b(t){let{projectRoot:e,...n}=t;try{return new q(e).dispatchBoundary(n).snapshot??null}catch(r){return f({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:t.sessionId,...t.turnId?{turnId:t.turnId}:{},...t.requestId?{requestId:t.requestId}:{},...t.executionId?{executionId:t.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:t.kind,reason:r instanceof Error?r.message:String(r),tool:t.producer}}),null}}var q=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let n=Dn(e.kind,e.payload??{});if(!n)return {handled:false};let r=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let o=xn(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:n.kind,payload:n.payload,idempotencyKey:`host:${o.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{r.close();}}};function xn(t,e){let n=e.executionId?t.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,r=e.turnId??n?.canonicalAction?.binding.turnId,o=e.requestId??n?.requestId;if(!r&&!o)return null;let i=t.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(l=>r?l.turnId===r:l.requestId===o);if(!i)return null;let s=t.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=t.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function Dn(t,e){switch(t){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 Mn=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu,On=/(?:记住|记下|保存|持久化|跨会话|以后|始终|永远|统一使用|项目约定|团队约定|偏好|决定采用|保留可复用|提炼结论|沉淀|记录(?:下来|为|成)?(?:架构|规则|约定|知识|结论))|\b(?:remember|memorize|persist|across sessions|from now on|always|project convention|team convention|preference|we use|adopt|retain reusable|distill)\b/iu,jn=/(?:分析|审查|检查|评估|性能|生成|创建|新建|添加|编写|实现|开发|设计|撰写|总结|修改|重构|修复|调试|解释|查看)|\b(?:analy[sz]e|review|inspect|audit|performance|generate|create|add|build|implement|develop|design|write|summarize|modify|refactor|fix|debug|explain)\b/iu,$n=/(?:召回|查询|检索|查找|定位|询问|什么|如何|是否|哪里|哪个)|\b(?:recall|query|search|find|locate|ask|what|how|whether|where|which)\b/iu;function Pn(t){let e=t.trim();return e.length>0&&!Mn.test(e)}function Fn(t,e){if(!e.trim())return false;let n=join(t,".devflow","delivery-line","state.db");if(!existsSync$1(n))return false;let r;try{return r=new DatabaseSync(n,{readOnly:!0,timeout:250}),r.prepare("SELECT payload FROM delivery_cases").all().some(i=>{try{let s=JSON.parse(i.payload);return s.sessionId===e&&!["delivered","cancelled","rejected"].includes(String(s.stage??""))}catch{return !1}})}catch{return false}finally{r?.close();}}function Nn(t){let e=t.normalize("NFKC").trim(),n=$n.test(e);return e.length>=4&&(jn.test(e)||n)&&(!On.test(e)||n)&&k(e)===null}function Hn(t,e,n=Date.now()){let r=createHash$1("sha256").update(e.trim()).digest("hex"),o=createHash$1("sha256").update(`${t}\0${n}\0${r}`).digest("hex").slice(0,24);return {turnId:`turn:${o}`,eventId:`memory-turn:${o}`,promptHash:r,createdAt:n}}function Me(t,e,n=[]){return `memory-receipt:${createHash$1("sha256").update(`${t}\0${e}\0${[...n].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ln(t){return `DevFlow memory decision required for ${t.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call ${projectClaudeToolName("memory_commit_turn")} with evidence-bound candidates, or ${projectClaudeToolName("memory_skip_turn")} with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function U(t){let e=t.memoryIds.length>0?t.memoryIds.join(","):"none",n=t.status==="committed"?"accepted":t.status,r=t.status==="committed"?"; indexStatus=pending":"",o=t.memoryIds.some(a=>a.startsWith("raw-memory:")),i=t.status==="committed"&&t.source==="explicit_intent"&&!o?"; memoryOnlyCompleted=true; skipProjectContext=true; hostRefinementRequired=true":t.status==="committed"&&t.source==="explicit_intent"?"; asyncReadiness=queued; hostRefinementRequired=true":"",s=t.status==="committed"&&t.source==="explicit_intent"?` The deterministic explicit-memory save is complete and remains authoritative if refinement fails. Before the final response, call ${projectClaudeToolName("memory_commit_turn")} once with turnId=${t.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=${n}; receiptId=${t.receiptId??"missing"}; turnId=${t.turnId}; memoryIds=${e}; source=${t.source??"unknown"}${r}${i}.`+s}function Oe(t){if(!Pn(t.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let n=t.prompt.trim().slice(0,4e3),r=createHash$1("sha256").update(n).digest("hex"),o=e.listMemoryTurns(t.projectRoot,t.sessionId,5).find(d=>d.promptHash===r&&Date.now()-d.createdAt<1e4),i=o?{turnId:o.turnId,eventId:o.eventId,promptHash:o.promptHash,createdAt:o.createdAt}:t.identity??Hn(t.sessionId,n),s=o??e.beginMemoryTurn({...i,projectRoot:t.projectRoot,sessionId:t.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:U(s),skipSkillRouting:s.source==="explicit_intent"};let l=(t.activation?.semantic??"degraded_structural")==="degraded_structural"?k(n)??void 0:void 0,m=Fn(t.projectRoot,t.sessionId);if(!l&&!m&&Nn(n)){let d=Me(s.turnId,"skipped"),p=e.skipMemoryTurn({turnId:s.turnId,receiptId:d,source:"automatic_transient_skip",reason:"high_confidence_transient_task"});return b({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,kind:"memory.skipped",payload:{receiptId:d,reasonCode:"high_confidence_transient_task"},dedupeKey:d,producer:"devflow-memory-turn"}),f({event:"memory.semantic.decided",identity:{projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId},level:"info",timestamp:Date.now(),data:{status:"semantic_empty",operation:"none",reason:"high_confidence_transient_task"}}),{turn:p,additionalContext:U(p),skipSkillRouting:!1}}let c=l?"commit_explicit":"capture_prompt",u=e.enqueueWork({idempotencyKey:`memory-turn:${c}:${s.turnId}`,kind:l?"memory.explicit_commit":"memory.turn_capture",projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,payload:{operation:c,turnId:s.turnId,eventId:s.eventId,sessionId:t.sessionId,prompt:n,explicitContent:l,createdAt:s.createdAt}});if(l){let d=`raw-memory:${createHash$1("sha256").update(`${t.projectRoot}\0${i.turnId}\0${l}`).digest("hex").slice(0,24)}`,p=Me(s.turnId,"committed",[d]),g=e.commitMemoryTurn({turnId:s.turnId,receiptId:p,memoryIds:[d],source:"explicit_intent",reason:"explicit_raw_queued",decidedAt:Date.now()});return b({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),b({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,kind:"memory.committed",payload:{receiptId:p,reasonCode:"explicit_raw_queued"},dedupeKey:p,producer:"devflow-memory-turn"}),f({event:"memory.write.completed",identity:{projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,actionReceipt:p},level:"info",timestamp:Date.now(),data:{stage:"explicit_fast_ack",durable:!0,rawMemoryId:d,receiptLatencyMs:Date.now()-i.createdAt,asyncReadiness:"queued"}}),{turn:g,explicitContent:l,additionalContext:U(g),skipSkillRouting:!0}}return b({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,kind:"memory.pending",payload:{reasonCode:"semantic_decision_queued"},dedupeKey:`${s.turnId}:pending`,producer:"devflow-memory-turn"}),b({projectRoot:t.projectRoot,sessionId:t.sessionId,turnId:s.turnId,kind:"durable_work.owned",payload:{workId:u.id,obligation:"memory"},dedupeKey:`${u.id}:owned`,producer:"devflow-memory-turn"}),{turn:s,explicitContent:l,additionalContext:Ln(s),skipSkillRouting:!1}}finally{e.close();}}function $e(t,e){let n=Vn(t);mkdirSync$1(n,{recursive:true,mode:448});let r=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID()}`,o=join(n,`${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 Vn(t){return join(w(t),"memory-turn-pending")}function Pe(t){let e=Date.now();try{let n=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let r=`context-prefetch:${createHash$1("sha256").update(`${t.projectRoot}\0${t.sessionId}\0${t.executionId}\0${Wn(t.prompt)}\0${t.profileFingerprint}`).digest("hex")}`,o=n.enqueueWork({idempotencyKey:r,kind:"context.prefetch",projectRoot:t.projectRoot,sessionId:t.sessionId,payload:t,maxAttempts:3});return h("prefetch_queue",{projectRoot:t.projectRoot,skillName:t.skillName,accepted:!0,workState:o.state,latencyMs:Date.now()-e}),{accepted:!0,workItemId:o.id}}finally{n.close();}}catch(n){let r=n instanceof Error?n.message:String(n);return h("prefetch_queue",{projectRoot:t.projectRoot,skillName:t.skillName,accepted:false,reason:r,latencyMs:Date.now()-e}),{accepted:false,reason:r}}}function Wn(t){return t.trim().toLowerCase().replace(/\s+/g," ").slice(0,4e3)}async function Le(t){let e=Date.now(),n=ar(t.projectRoot),r=claudeCodeRuntimeAdapter.normalizePrompt(t.hostEvent??{session_id:t.sessionId,prompt:t.prompt},{projectRoot:n}),o=semanticTextHash(He(r.rawPrompt)),i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:100});try{let s=i.getTaskIntentArtifactBySource({projectRoot:n,sessionId:t.sessionId,sourceHash:o});if(s){let j=Fe(s).identity,z=i.getRuntimeActivation(j.projectRoot,j.sessionId,j.turnId,s.version);if(!z)throw new Error(`RUNTIME_ACTIVATION_MISSING:${s.artifactHash}`);return {artifact:Fe(s),memoryIdentity:Ne(s),activation:z,reused:!0}}let a=`turn:${O(`${t.sessionId}\0${o}`)}`,l=`request:${O(`${n}\0${t.sessionId}\0${a}`)}`,m={projectRoot:n,projectId:`project:${stableRuntimeHash(n).slice(0,20)}`,hostId:r.hostId,sessionId:t.sessionId,executionId:t.sessionId,turnId:a,requestId:l},c=1,u=resolveRuntimeActivationSnapshot({projectRoot:n,createdAt:r.timestamp}),d=ir(r.rawPrompt),p={identity:m,version:c,rawPrompt:r.rawPrompt,normalizedPrompt:He(r.rawPrompt),...r.command?{command:r.command}:{},slashArgs:r.slashArgs,...r.activeSkill?{activeSkill:r.activeSkill}:{},intent:"unknown",action:"unknown",entities:[],targetAnchors:d,policyConstraints:[],classificationEvidence:[],sourceEventIds:[r.sourceEventId??`host-event:${o.slice(0,24)}`],sourceHash:o,createdAt:r.timestamp},g={...p,artifactHash:cr(p)};i.appendTaskIntentArtifact(rr(g)),i.bindRuntimeActivation({identity:m,revision:c,snapshot:u});let ze=nr(i,g);return f({event:"host.prompt.normalized",identity:m,level:"info",timestamp:Date.now(),data:{sourceHash:o,command:g.command,activeSkill:g.activeSkill,rawPromptBytes:Buffer.byteLength(g.rawPrompt)}}),f({event:"intent.artifact.created",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:g.artifactHash,targetCount:d.length}}),f({event:"intent.artifact.persisted",identity:m,level:"info",timestamp:Date.now(),data:{artifactHash:g.artifactHash,version:g.version,sourceHash:g.sourceHash,authority:"immutable-intent",captureLatencyMs:Date.now()-e}}),f({event:"terminal.transition.persisted",identity:m,level:"info",timestamp:Date.now(),data:{state:"intent_bound",receiptId:ze,sourceIntentHash:g.artifactHash}}),{artifact:g,memoryIdentity:Ne(g),activation:u,reused:!1}}finally{i.close();}}function nr(t,e){let n=t.getLatestTerminalTransition(e.identity.projectRoot,e.identity.sessionId,e.identity.turnId);if(n)return n.receiptId;let r=`terminal:${O(`${e.artifactHash}\0open`)}`;return t.appendTerminalTransition({...e.identity,sequence:1,toState:"open",receiptId:r,reason:"host_prompt_accepted",payload:{sourceHash:e.sourceHash},createdAt:e.createdAt}),t.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 rr(t){return {...t.identity,version:t.version,supersedesHash:t.supersedesHash,rawPrompt:t.rawPrompt,normalizedPrompt:t.normalizedPrompt,command:t.command,slashArgs:t.slashArgs,activeSkill:t.activeSkill,intent:t.intent,action:t.action,entities:t.entities,targetAnchors:t.targetAnchors,policyConstraints:t.policyConstraints,classificationEvidence:t.classificationEvidence.map(e=>({...e})),sourceEventIds:t.sourceEventIds,sourceHash:t.sourceHash,artifactHash:t.artifactHash,createdAt:t.createdAt}}function Fe(t){return {identity:or(t),version:t.version,...t.supersedesHash?{supersedesHash:t.supersedesHash}:{},rawPrompt:t.rawPrompt,normalizedPrompt:t.normalizedPrompt,...t.command?{command:t.command}:{},slashArgs:t.slashArgs,...t.activeSkill?{activeSkill:t.activeSkill}:{},intent:t.intent,action:t.action,entities:t.entities,targetAnchors:t.targetAnchors,policyConstraints:t.policyConstraints,classificationEvidence:t.classificationEvidence,sourceEventIds:t.sourceEventIds,sourceHash:t.sourceHash,artifactHash:t.artifactHash,createdAt:t.createdAt}}function or(t){return {projectRoot:t.projectRoot,projectId:t.projectId,hostId:t.hostId,sessionId:t.sessionId,turnId:t.turnId,requestId:t.requestId,...t.executionId?{executionId:t.executionId}:{}}}function Ne(t){let e=t.rawPrompt.trim().slice(0,4e3),n="identity"in t?t.identity.turnId:t.turnId;return {turnId:n,eventId:`memory-turn:${n.replace(/^turn:/u,"")}`,promptHash:createHash$1("sha256").update(e).digest("hex"),createdAt:t.createdAt}}function ir(t){let e=t.match(/(?:^|[\s`'"(])((?:\.{0,2}\/)?(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+(?:\.[A-Za-z0-9]+)?)/gu)??[];return sr(e.map(n=>n.trim().replace(/^[`'"(]+|[`'"),.;:,。;:]+$/gu,"")).filter(n=>!n.startsWith("/")||/\.[A-Za-z0-9]+$/u.test(n))).slice(0,16)}function He(t){return t.normalize("NFKC").replace(/\s+/gu," ").trim().slice(0,4e3)}function sr(t){return [...new Set(t.filter(Boolean))]}function ar(t){let e=resolve(t);try{return realpathSync(e)}catch{return e}}function cr(t){return createHash$1("sha256").update(J(t)).digest("hex")}function O(t){return createHash$1("sha256").update(t).digest("hex").slice(0,24)}function J(t){if(t===null||typeof t=="string"||typeof t=="boolean")return JSON.stringify(t);if(typeof t=="number")return Number.isFinite(t)?JSON.stringify(t):"null";if(Array.isArray(t))return `[${t.map(J).join(",")}]`;if(!t||typeof t!="object")return JSON.stringify(String(t));let e=t;return `{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${J(e[n])}`).join(",")}}`}function Ue(){return generateKeyPairSync("ed25519")}function Ke(t){let e=parseTrustedDecisionCommand(t.rawUserEvent,t.allowedOptionIds),n=t.now??Date.now(),r={schemaVersion:"delivery-user-attestation.v1",issuer:t.issuer,keyId:t.keyId,purpose:e.purpose,decisionId:e.decisionId,caseId:t.caseId,caseVersion:t.caseVersion,sessionId:t.sessionId,sourceTurnId:t.sourceTurnId,actorId:t.actorId,targetDecisionHash:t.targetDecisionHash,rawUserEvent:t.rawUserEvent,rawUserEventHash:domainHash("raw-user-event",t.rawUserEvent),selectedValueHash:domainHash("decision-value",{decisionId:e.decisionId,purpose:e.purpose,value:encodeDecisionValue(e.purpose,e.value)}),eventSequence:t.eventSequence,issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+6e4).toISOString(),nonce:t.nonce};return {...r,attestation:sign(null,canonicalJsonBytes(r),t.privateKey).toString("base64url")}}var Je=new Map;async function Ve(t){let e=t.prompt.trim();if(!/^\/devflow:(?:decide|approve|reject|revise|cancel|exit)\b/u.test(e))return {handled:false};let n=hr(t.projectRoot),r=e;if(e==="/devflow:approve"||e==="/devflow:approve current"){let c=await n.pendingDecisionForSession(t.sessionId);if(!c)return {handled:true,resolved:false,message:"DevFlow approval not found: there is no pending decision for this session."};if("ambiguous"in c)return {handled:true,resolved:false,message:`DevFlow approval is ambiguous: multiple pending cases exist (${c.caseIds.join(", ")}). Use the approval choices shown by the host.`};if(c.decision.kind!=="artifact_approval")return {handled:true,resolved:false,message:"DevFlow approval is not available yet: the current pending item is a clarification, not an artifact gate."};r=`/devflow:approve ${c.decision.id}`;}let o;try{o=parseTrustedDecisionCommand(r);}catch(c){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${c instanceof Error?c.message:String(c)}`}}let i=o.decisionId.split(/:(?:decision|question|approval):/u)[0],s=await n.pendingDecision(i);if(!s||s.id!==o.decisionId)return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: no pending decision matches ${o.decisionId}. Refresh delivery_status.`};let a=process.env.DEVFLOW_HOST_ACTOR_ID?.trim()||`user:${process.env.USER?.trim()||"local"}`,l=Ue(),m=Ke({rawUserEvent:r,issuer:"claude-code",keyId:"session-ephemeral",caseId:i,caseVersion:s.caseVersion,sessionId:t.sessionId,sourceTurnId:t.sourceTurnId?.trim()||`host-turn:${t.sessionId}:${Date.now()}`,actorId:a,targetDecisionHash:s.targetDecisionHash,eventSequence:Date.now(),nonce:randomUUID(),privateKey:l.privateKey,allowedOptionIds:s.options.map(c=>c.id)});try{return await n.resolveTrustedDecision({evidence:m,publicKey:l.publicKey,expectedIssuer:"claude-code",expectedKeyId:"session-ephemeral"}),{handled:!0,resolved:!0,message:`DevFlow trusted decision resolved for ${i}. Refresh delivery_status and follow nextActions.`}}catch(c){return {handled:true,resolved:false,message:`DevFlow trusted decision rejected: ${c instanceof Error?c.message:String(c)}`}}}function hr(t){let e=Je.get(t);if(e)return e;let n=createTrustedDeliveryFacade(t);return Je.set(t,n),n}var y=process.env.CLAUDE_PROJECT_DIR||process.cwd();async function br(t){let e=W()?[B]:[],n;try{n=JSON.parse(t);}catch{return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
10
|
+
`)}:{}}}}let r=n.prompt||"";if(!r.trim())return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
11
|
+
`)}:{}}};let o=n.session_id?.trim();if(o&&/^\/devflow:(?:decide|approve|reject)\b/u.test(r.trim()))try{let c=await Ve({projectRoot:y,sessionId:o,prompt:r});if(c.handled)return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:c.message}}}catch(c){e.push(`DevFlow trusted delivery fallback degraded: ${c instanceof Error?c.message:String(c)}`);}let i=se(r),s=false,a,l,m=o?new x(y):void 0;if(o){try{l=await Le({projectRoot:y,sessionId:o,prompt:r,hostEvent:n}),m.bindTaskIdentity(o,{turnId:l.artifact.identity.turnId,requestId:l.artifact.identity.requestId,intentArtifactHash:l.artifact.artifactHash}),e.push(`DevFlow immutable task identity: turnId=${l.artifact.identity.turnId}; requestId=${l.artifact.identity.requestId}; intentArtifactHash=${l.artifact.artifactHash}. Retrieval query expansion must not replace this original intent.`);}catch(c){e.push("DevFlow task intent persistence degraded; preserve the original user command and do not claim canonical context binding."),f({event:"intent.artifact.failed",identity:{projectRoot:y,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"user_prompt_submit",category:"intent_persistence_unavailable",error:c instanceof Error?c.message:String(c)}});}try{let c=Oe({projectRoot:y,sessionId:o,prompt:r,...l?{identity:l.memoryIdentity}:{},...l?{activation:l.activation}:{}});c&&(e.push(c.additionalContext),s=c.skipSkillRouting);}catch(c){s=!!k(r);try{let u=$e(y,{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.`),f({event:"memory.write.degraded",identity:{projectRoot:y,sessionId:o},level:"warn",timestamp:Date.now(),data:{stage:"turn_capture",reason:c.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."),f({event:"memory.write.degraded",identity:{projectRoot:y,sessionId:o},level:"error",timestamp:Date.now(),data:{stage:"turn_capture",reason:u.message,fallback:"none"}});}}}if(o&&i&&!s){let c=m.get(o)?.executionId,u=m.startExecution(o,i.skillName,fe(i.skillName));if(a=u.executionId,u.executionId&&u.executionId!==c){let p=new C;try{await p.sendSessionStart(o,y,u.startedAt),await p.sendExecutionStart(u.executionId,o,i.skillName,u.lastActivityAt,y,u.requiredMcpTools);}finally{p.close();}}let d=ge(i.skillName,y,r);d&&e.push(d);}if(o&&i&&a&&!s){let c=resolveProjectCapabilityProfile(y),u=resolveCapabilityRollout(y).config.retrievalSessions;Pe({prompt:r.trimStart().replace(/^\/devflow:[a-z0-9][a-z0-9-]*\b/i,"").trim()||r,projectRoot:y,sessionId:o,executionId:a,skillName:i.skillName,profileFingerprint:c.fingerprint,rolloutMode:u,retrievalVersion:"r2.v1",createdAt:Date.now()});}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...e.length?{additionalContext:e.join(`
|
|
12
|
+
`)}:{}}}}if(process.argv[1]?.endsWith("user-prompt-submit")||process.argv[1]?.endsWith("user-prompt-submit.js")){let t=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",n=>{e+=n;}),process.stdin.on("end",async()=>{let n=await br(e.trim()||process.argv[2]||"");t(JSON.stringify(n)),process.exit(0);}),process.stdin.on("error",()=>{t(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);}),setTimeout(()=>{t(JSON.stringify({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow"}})),process.exit(0);},3e4).unref();}export{br as handleUserPromptSubmit};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifestVersion": "devflow-runtime.v1",
|
|
3
|
-
"packageVersion": "0.19.
|
|
4
|
-
"sourceCommit": "
|
|
3
|
+
"packageVersion": "0.19.11",
|
|
4
|
+
"sourceCommit": "a9cb69a06f0e49285d67614cb039eaf5deb39d93",
|
|
5
5
|
"bundleHashes": {
|
|
6
|
-
"hooks": "
|
|
7
|
-
"mcp": "
|
|
6
|
+
"hooks": "858e24cc2bc01cdc69e47010e9e51eafc9d9230c9799a421821c3aa917f9c062",
|
|
7
|
+
"mcp": "0fa7e886d73d154311629ae3c16bb118eb938002af9da41f5d24daebb3ca708e",
|
|
8
8
|
"cli": "6205081f819ee3651962df36edd626b993a917fb8691f20c84e6b6e04af81d16"
|
|
9
9
|
},
|
|
10
|
-
"registryHash": "
|
|
10
|
+
"registryHash": "467030836beede7accd7909089e905a1b188e714387e8f47853db9f4c557e3cc",
|
|
11
11
|
"stateDbPath": "<projectRoot>/.devflow/delivery-line/state.db",
|
|
12
|
-
"builtAt":
|
|
13
|
-
"manifestHash": "
|
|
12
|
+
"builtAt": 1793867974816,
|
|
13
|
+
"manifestHash": "bc88f09432e0f641fc6eb7ca9156fda38ff6cc2ef63cdb3cc756c99ab43ddc46"
|
|
14
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/claude-code-plugin",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.11",
|
|
4
4
|
"description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,20 +12,20 @@
|
|
|
12
12
|
"verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@devflow-tools/benchmark": "0.19.
|
|
16
|
-
"@devflow-tools/context-engine": "0.19.
|
|
17
|
-
"@devflow-tools/database": "0.19.
|
|
18
|
-
"@devflow-tools/mcp-server": "0.19.
|
|
19
|
-
"@devflow-tools/memory-engine": "0.19.
|
|
20
|
-
"@devflow-tools/sdk": "0.19.
|
|
21
|
-
"@devflow-tools/semantic-engine": "0.19.
|
|
22
|
-
"@devflow-tools/server": "0.19.
|
|
23
|
-
"@devflow-tools/task-runtime": "0.19.
|
|
24
|
-
"@devflow-tools/telemetry": "0.19.
|
|
25
|
-
"@devflow-tools/workflow-engine": "0.19.
|
|
15
|
+
"@devflow-tools/benchmark": "0.19.11",
|
|
16
|
+
"@devflow-tools/context-engine": "0.19.11",
|
|
17
|
+
"@devflow-tools/database": "0.19.11",
|
|
18
|
+
"@devflow-tools/mcp-server": "0.19.11",
|
|
19
|
+
"@devflow-tools/memory-engine": "0.19.11",
|
|
20
|
+
"@devflow-tools/sdk": "0.19.11",
|
|
21
|
+
"@devflow-tools/semantic-engine": "0.19.11",
|
|
22
|
+
"@devflow-tools/server": "0.19.11",
|
|
23
|
+
"@devflow-tools/task-runtime": "0.19.11",
|
|
24
|
+
"@devflow-tools/telemetry": "0.19.11",
|
|
25
|
+
"@devflow-tools/workflow-engine": "0.19.11"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@devflow-tools/devflow": "0.19.
|
|
28
|
+
"@devflow-tools/devflow": "0.19.11"
|
|
29
29
|
},
|
|
30
30
|
"allowScripts": {
|
|
31
31
|
"better-sqlite3@12.11.1": true,
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"hooks",
|
|
51
51
|
"skills"
|
|
52
52
|
],
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "a9cb69a06f0e49285d67614cb039eaf5deb39d93",
|
|
54
54
|
"license": "MIT",
|
|
55
55
|
"repository": {
|
|
56
56
|
"type": "git",
|
|
@@ -86,7 +86,10 @@ integration ref)完整保留。执行车辆是会话本身,交付线只做
|
|
|
86
86
|
|
|
87
87
|
流程(对每个 pending 任务重复 2-6):
|
|
88
88
|
|
|
89
|
-
1.
|
|
89
|
+
1. `plan_approved` 阶段且 `nextActions` 含 `begin_foreground_execution` 时,必须先用 `AskUserQuestion`
|
|
90
|
+
询问执行方式(前台执行 / 后台 worker)——这是机器语义 gate,不得跳过询问直接 resume。
|
|
91
|
+
选前台后调用 `mcp__plugin_devflow_devflow__delivery_begin_foreground_execution` 获取任务租约
|
|
92
|
+
(此后宿主会话的 Write/Edit/Bash 对本案件放行——你就是在受审计地扮演 worker)。
|
|
90
93
|
2. 从 `delivery_status` 的任务列表取第一个 `pending` 任务,向用户展示任务卡:目标、`allowedFiles`、
|
|
91
94
|
`implementationSteps`(RED/GREEN 顺序)、验收标准、验证命令。明确声明 allowedFiles 之外不做任何修改。
|
|
92
95
|
3. 基于任务的 base revision 建独立 worktree(候选必须是 base 后代,否则 import 会被权威校验拒绝):
|
|
@@ -102,6 +105,23 @@ integration ref)完整保留。执行车辆是会话本身,交付线只做
|
|
|
102
105
|
边界:前台模式不改变 Delivery authority——不碰 target ref、不跳过验证、不伪造证据;import 失败照常
|
|
103
106
|
按错误处理规则恢复。
|
|
104
107
|
|
|
108
|
+
## 人工 Review Gate(REVIEW_AWAITING_HUMAN)
|
|
109
|
+
|
|
110
|
+
案件到达 `verified` 后,`delivery_resume` 会以 `REVIEW_AWAITING_HUMAN` blocker 挂起——集成修订必须经
|
|
111
|
+
过人工三类审查才能进入 `reviewed`/导出。这是产品设计的强制审计环节,不是故障。
|
|
112
|
+
|
|
113
|
+
流程:
|
|
114
|
+
1. 收到 `REVIEW_AWAITING_HUMAN` 后,先向用户展示审查材料:集成 diff(`git diff <parentRevision>..<integrationRevision>`)、
|
|
115
|
+
验证证据摘要(verification 命令与结果)、任务验收标准。
|
|
116
|
+
2. 用 `AskUserQuestion` 一次收集三类裁决(bugs / security / compliance),每类选项:通过 / 退回(附 finding)。
|
|
117
|
+
用户的裁决必须原样提交,不得代答或合并。
|
|
118
|
+
3. 调用 `delivery_submit_review(caseId, verdicts)` 提交三类 verdict(每项 `{ kind, passed, findings? }`,
|
|
119
|
+
findings 的 severity 用 blocker/major/minor/informational)。宿主可信通道会签名该决策。
|
|
120
|
+
4. 读取返回状态:全部通过 → `reviewed`,按 `nextActions` 进入 release 审批与 `delivery_export`;
|
|
121
|
+
任一退回 → `needs_changes`,按恢复路径修订后重走执行/导入。
|
|
122
|
+
|
|
123
|
+
禁止:agent 不得代替用户生成 verdict;不得在未展示 diff 与验证证据的情况下请求裁决;三类缺一不可。
|
|
124
|
+
|
|
105
125
|
## 可用操作
|
|
106
126
|
|
|
107
127
|
- 澄清和设计:`delivery_propose_options`、`delivery_answer`、`delivery_revise`、`delivery_compare_options`、`delivery_prepare_plan`
|