@devflow-tools/cli 0.16.20 → 0.16.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/eval.d.ts +16 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +102 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/plugin-guide.d.ts.map +1 -1
- package/dist/commands/plugin-guide.js +6 -29
- package/dist/commands/plugin-guide.js.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin-files/.claude-plugin/plugin.json +1 -1
- package/dist/plugin-files/dist/command-registry.json +5 -5
- package/dist/plugin-files/dist/hooks/hook-daemon.js +22 -21
- package/dist/plugin-files/dist/hooks/pre-tool-use.js +1 -1
- package/dist/plugin-files/dist/hooks/user-prompt-submit.js +8 -8
- package/dist/plugin-files/hooks/session-start +47 -1
- package/dist/plugin-files/package.json +7 -7
- package/package.json +26 -26
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import {createServer,createConnection}from'net';import {createHash,randomUUID as randomUUID$1}from'node:crypto';import {join as join$1,dirname}from'path';import {mkdirSync,lstatSync,openSync,writeFileSync,fstatSync,closeSync,readFileSync,unlinkSync,existsSync as existsSync$1,readdirSync,rmSync,linkSync,renameSync as renameSync$1}from'fs';import {getLocalApiKey,getDaemonSocketPath,getDaemonPidPath,
|
|
2
|
-
`);}catch{}}function Wo(n){return new Promise(e=>setTimeout(e,n))}var Nt=1e4,Go=3e4,ne=500,O=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=e?.legacyCacheDir??(e?.cacheDir?null:join$1(homedir$1(),".devflow","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,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",o=Date.now(),r){let i={executionId:e,status:t,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,o){let r={id:e,projectRoot:t,startedAt:o,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),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 o={sessionId:e,finishedAt:t},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),r}async flushCache(){try{let o=this.getDatabase(),r=o.listTelemetryFailures({unresolvedOnly:!0,limit:ne}).reverse();for(let i of r)try{this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id);}catch{}o.trimTelemetryFailures(ne);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(o=>!!o))].filter(o=>existsSync$1(o)).flatMap(o=>readdirSync(o).filter(r=>r.endsWith(".json")).map(r=>{let i=join$1(o,r);try{return {cacheFile:i,envelope:Vo(JSON.parse(readFileSync(i,"utf8")),r)}}catch{return null}})).filter(o=>o!==null).sort((o,r)=>o.envelope.timestamp-r.envelope.timestamp||Lt(o.envelope.operation)-Lt(r.envelope.operation));for(let{cacheFile:o,envelope:r}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),i.resolveTelemetryFailure(r.id),unlinkSync(o);}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(o){return this.cacheOperation(e,t,o),false}}applyOperation(e,t){let o=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(o,t),o.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(o,t),o.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":o.ensureSession(t),o.insertRun({id:Ht(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(!o.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":o.closeSession(t.sessionId,t.finishedAt),o.updateRun(Ht(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let o=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=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:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:r}),s.trimTelemetryFailures(ne),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-ne)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},Go).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){M(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Nt?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Nt)}...`}}};function Lt(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function Ht(n){return `hook-run:${n}`}function Vo(n,e){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.operation=="string"&&t.payload!==void 0)return t;let o=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!o)throw new Error("Unknown legacy telemetry cache operation");let r=t.payload??{},i=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:o,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}function oe(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(oe(n))}var er=2,tr=1;function nr(){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 Ut(n=nr()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync$1(t))continue;let o=JSON.parse(readFileSync(t,"utf8"));if(o.version!==er&&o.version!==tr||!or(o.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return o.commands}catch(o){console.error(`[devflow] command registry load failed: ${o.message}`);}return null}function or(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 je(t.mcpTools)&&je(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||je(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function je(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function Wt(n){let e=Ut();return e?e[n]?.mcpTools??[]:[]}var $e=join$1(homedir$1(),".devflow"),Ne=join$1($e,"server-refs.json"),pr=600*1e3,mr=500;function fr(){existsSync$1($e)||mkdirSync($e,{recursive:true});}function re(){try{if(existsSync$1(Ne))return JSON.parse(readFileSync(Ne,"utf-8"))}catch{}return {sessions:[],lastActivity:0}}function zt(n){fr(),writeFileSync(Ne,JSON.stringify(n));}var se=class{constructor(e){this.process=null;this.idleTimer=null;this.onShutdown=null;this.ownerToken=null;this.projectRoot=e;}setOnShutdown(e){this.onShutdown=e;}addRef(e){let t=re();t.sessions.includes(e)||t.sessions.push(e),t.lastActivity=Date.now(),zt(t),this.resetIdleTimer();}removeRef(e){let t=re();t.sessions=t.sessions.filter(o=>o!==e),t.lastActivity=Date.now(),zt(t),t.sessions.length===0&&this.resetIdleTimer();}get activeSessions(){return re().sessions.length}async ensureRunning(){return await this.healthCheck()?true:(await this.startServer(),this.waitForReady())}get isRunning(){return this.process!==null&&!this.process.killed}async stop(){if(this.idleTimer&&clearTimeout(this.idleTimer),this.process){this.process.kill("SIGTERM"),await new Promise(t=>{let o=setTimeout(()=>{this.process&&!this.process.killed&&this.process.kill("SIGKILL"),t();},5e3);this.process?this.process.on("exit",()=>{clearTimeout(o),t();}):(clearTimeout(o),t());}),this.process=null;let e=readRuntimeEndpointState();e&&e.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped");}}async startServer(){let e=hr(this.projectRoot);this.ownerToken=randomUUID$1();let t=resolveRuntimeEndpoint();this.process=spawn(process.execPath,[e,"--devflow-instance-token",this.ownerToken],{cwd:this.projectRoot,env:{...process.env,NODE_ENV:process.env.NODE_ENV||"development"},stdio:["ignore","pipe","pipe"]}),writeRuntimeEndpointState({url:t.url,port:t.port,pid:this.process.pid??0,ownerToken:this.ownerToken,status:"launching"}),this.process.stdout?.on("data",o=>{}),this.process.stderr?.on("data",o=>{}),this.process.on("exit",o=>{let r=readRuntimeEndpointState();r&&r.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped"),this.process=null,this.onShutdown&&this.onShutdown();}),this.process.on("error",()=>{let o=readRuntimeEndpointState();o&&o.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("degraded"),this.process=null;});}async waitForReady(){let e=Date.now()+3e4;for(;Date.now()<e;){if(await this.healthCheck())return true;await new Promise(t=>setTimeout(t,mr));}return false}healthCheck(){return new Promise(e=>{let t=resolveRuntimeEndpoint(),o=new URL("/api/health",t.url),r=request({hostname:o.hostname,port:o.port,path:o.pathname,method:"GET",timeout:2e3},i=>{let s=i.statusCode===200;s&&readRuntimeEndpointState()&&updateRuntimeEndpointStatus("healthy"),i.resume(),e(s);});r.on("error",()=>e(false)),r.on("timeout",()=>{r.destroy(),e(false);}),r.end();})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),!(re().sessions.length>0)&&(this.idleTimer=setTimeout(()=>{this.stop();},pr).unref());}};function hr(n){let e=createRequire(import.meta.url),t=[()=>e.resolve("@devflow-tools/server/dist/main.js"),()=>join$1(n,"node_modules","@devflow-tools","server","dist","main.js"),()=>join$1(n,"apps","server","dist","main.js")];for(let o of t)try{let r=o();if(existsSync$1(r))return r}catch{}throw new Error("DevFlow server entry point is not installed or built")}function ae(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let e=n,t={};for(let o of ["lastMcpCall","bypassCount"])if(o in e){let r=e[o];if(r==null)continue;t[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return t}function vr(n,e){return n.lastMcpCall===e.lastMcpCall&&n.bypassCount===e.bypassCount}function br(n){try{return existsSync$1(n)?ae(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function Sr(n,e){let t=e instanceof Error?e.message:String(e);console.error(`[devflow] Receipt ${n} skipped: ${t}`);}function qt(n){let e=E(n);for(let t of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync$1(join$1(e,t))&&unlinkSync(join$1(e,t));}catch{}}function _r(n,e){if(n.getHookReceipt(e)){qt(e);return}let t=join$1(E(e),"receipt.json");if(!existsSync$1(t))return;let o=br(t);n.updateHookReceipt(e,()=>o),qt(e);}function Gt(n,e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),_r(o,n);let r={},i=o.updateHookReceipt(n,a=>(r=ae(a),ae(e(r)))),s=ae(i);return {receipt:s,applied:!0,changed:!vr(r,s)}}catch(r){return Sr(t,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function ce(n,e){return Gt(n,()=>e,"write").applied}function We(n,e){return Gt(n,e,"update")}var Jt={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function wr(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var B=class{constructor(e,t,o){this.projectRoot=e;this.sessionId=t;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let t=e.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(t&&t.expiresAt>Date.now())return "context_ready";t&&e.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{e?.close();}catch{}}return "context_gathering"}evaluate(e,t){let o=this.getPhase();if(t||e==="Skill")return {permissionDecision:"allow"};if(o==="context_gathering"&&Jt[e])return {permissionDecision:"deny",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${e}.`};if(o==="context_ready")return {permissionDecision:"allow"};let r=Jt[e];if(!r)return {permissionDecision:"allow"};let i=We(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=wr(e);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${e}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){ce(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}};var Tr=10,Mr=5e3,Dr=3e4,Cr=new Int32Array(new SharedArrayBuffer(4)),Zt=0;function Or(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.rootPath=="string"&&e.rootPath.length>0&&typeof e.projectHash=="string"&&e.projectHash.length>0&&typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.startedAt=="number"&&Number.isFinite(e.startedAt)&&e.startedAt>=0}function en(n){if(!existsSync(n))return {entries:[],needsRepair:false};try{let e=JSON.parse(readFileSync$1(n,"utf8"));if(!Array.isArray(e))return {entries:[],needsRepair:!0};let t=e.filter(Or);return {entries:t,needsRepair:t.length!==e.length}}catch{return {entries:[],needsRepair:true}}}function tn(n,e){mkdirSync$1(dirname$1(n),{recursive:true});let t=`${n}.${process.pid}.${Date.now()}.${Zt++}.tmp`,o;try{o=openSync$1(t,"wx"),writeFileSync$1(o,JSON.stringify(e,null,2)),closeSync$1(o),o=void 0,renameSync(t,n);}finally{try{o!==void 0&&closeSync$1(o);}finally{rmSync$1(t,{force:true});}}}function nn(n){try{return process.kill(n,0),!0}catch(e){return e.code!=="ESRCH"}}function on(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function Vt(n,e){try{return readFileSync$1(n,"utf8")!==e?!1:(rmSync$1(n),!0)}catch(t){return t.code==="ENOENT"}}function Ar(n){try{let e=readFileSync$1(n,"utf8"),t;try{let r=JSON.parse(e);on(r)&&(t=r);}catch{}return t?nn(t.pid)?!1:Vt(n,e):Date.now()-statSync(n).mtimeMs>Dr&&Vt(n,e)}catch(e){return e.code==="ENOENT"}}function Pr(n){mkdirSync$1(dirname$1(n),{recursive:true});let e=`${n}.lock`,t=Date.now()+Mr;for(;;){let o=`${process.pid}:${Date.now()}:${Zt++}`,r;try{return r=openSync$1(e,"wx"),writeFileSync$1(r,JSON.stringify({pid:process.pid,createdAt:Date.now(),token:o})),closeSync$1(r),r=void 0,{path:e,token:o}}catch(i){if(r!==void 0)try{closeSync$1(r);}finally{rmSync$1(e,{force:true});}if(i.code!=="EEXIST")throw i}if(!Ar(e)){if(Date.now()>=t)throw new Error(`Timed out acquiring daemon registry lock: ${e}`);Atomics.wait(Cr,0,0,Tr);}}}function jr(n){try{let e=readFileSync$1(n.path,"utf8"),t=JSON.parse(e);on(t)&&t.token===n.token&&rmSync$1(n.path);}catch(e){if(e.code!=="ENOENT")throw e}}function rn(n){let e=getDaemonRegistryPath(),t=Pr(e);try{return n(e)}finally{jr(t);}}function sn(n,e){rn(t=>{let o=en(t).entries.filter(r=>r.rootPath!==n&&nn(r.pid));o.push({rootPath:n,projectHash:getProjectHash(n),pid:e,startedAt:Date.now()}),tn(t,o);});}function an(n,e){rn(t=>{let o=en(t).entries.filter(r=>r.rootPath!==n||e!==void 0&&r.pid!==e);tn(t,o);});}async function G(n){let e=!n.memory,t=n.memory??new MemoryGate(n.projectRoot),o=0,r=0;try{await t.forceWarmUp(),n.trigger==="session_end"&&(o=await t.releasePendingDistillLeases(n.sessionId)),r=t.getPendingEventCount(n.sessionId,n.trigger!=="session_end");}finally{e&&t.close();}let i={pendingEvents:r,releasedLeases:o,trigger:n.trigger,sessionId:n.sessionId,details:n.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),c=n.trigger==="session_end"&&n.sessionId?`distill:session_end:${createHash("sha256").update(`${n.projectRoot}\0${n.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:c,projectRoot:n.projectRoot,sessionId:n.sessionId,trigger:n.trigger,pendingEvents:r,releasedLeases:o,details:n.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...i,projectRoot:n.projectRoot}});}finally{s.close();}}catch(s){if(n.strictPersistence)throw s}return i}function cn(n){if(n.pendingEvents===0)return "";let e=n.sessionId?`\uFF0CsessionId=${n.sessionId}`:"";return `Memory distill checkpoint: ${n.pendingEvents} \u4E2A\u4E8B\u4EF6\u5F85\u63D0\u70BC${e}\u3002\u4E0A\u4E0B\u6587\u538B\u7F29\u5B8C\u6210\u540E\uFF0C\u8C03\u7528 mcp__devflow__memory_request_distill\uFF1B\u6309\u8FD4\u56DE\u7684 nextPage \u5206\u9875\u8BFB\u53D6\u5168\u90E8\u4E8B\u4EF6\uFF0C\u63D0\u70BC observations\uFF0C\u518D\u8C03\u7528 mcp__devflow__memory_save_distilled \u5E76\u786E\u8BA4\u4FDD\u5B58\u7ED3\u679C\u3002`}function pn(n){return Buffer.from(n,"utf8").toString("base64url")}function Wr(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function vn(n){return `${n}:legacy-journal`}var T=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(E(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=mn(i.evidenceObligations),i.evidenceDegradations=fn(i.evidenceDegradations),i.evidenceOutcomes=hn(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??Wr(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(u=>u.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(u=>u.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(u=>u.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${pn(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",pn(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=mn(e.evidenceObligations),e.evidenceDegradations=fn(e.evidenceDegradations),e.evidenceOutcomes=hn(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=zr(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||gn(i.kind)-gn(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!o&&(t.kind==="degrade"&&e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i}),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),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function mn(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)||!bn(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:vn(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function fn(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 hn(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 zr(n){if(!n||typeof n!="object")return null;let e=n;if(!["add","correction","resolve","degrade"].includes(e.kind??"")||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let t=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:vn(e.contractId);if(e.kind==="add")return bn(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let o=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(e.violations)&&e.violations.every(r=>typeof r=="string"&&r.length<=240)?{...e,obligationId:t,fingerprint:o}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function gn(n){return n==="add"?0:n==="correction"?1:2}function bn(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function wn(n,e){let t=En(n);mkdirSync$1(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync$1(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function kn(n){let e=En(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.receiptId!="string"||typeof s.inputJson!="string"||typeof s.sessionId!="string"||typeof s.cleanupSharedState!="boolean")throw unlinkSync$1(i),new Error("session_finalize_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Rn(n){unlinkSync$1(n.path);}function In(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function En(n){return join(E(n),"session-finalize-pending")}var ei=256*1024,ti=48*1024,ni=512*1024,oi=500,ri=5,V=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ii(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function si(n){let e=K(n,0,new Set);return e?yi(e.contract,e.canonicalReport):null}function Mn(n){if(!n.sessionId||!ii(n.toolName))return null;let e=si(n.toolResponse);if(!e)return null;let t=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,e,t,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:e,runtimeObligationId:o.obligationId},createdAt:t,updatedAt:t});}finally{i.close();}}return ai(e)}function ai(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
|
|
1
|
+
import {createServer,createConnection}from'net';import {createHash,randomUUID as randomUUID$1}from'node:crypto';import {execFileSync}from'node:child_process';import {join as join$1,dirname}from'path';import {mkdirSync,lstatSync,openSync,writeFileSync,fstatSync,closeSync,readFileSync,unlinkSync,existsSync as existsSync$1,readdirSync,rmSync,linkSync,renameSync as renameSync$1}from'fs';import {getLocalApiKey,getDaemonSocketPath,getDaemonPidPath,resolveCapabilityRollout,loadConfig,readRuntimeEndpointState,updateRuntimeEndpointStatus,resolveRuntimeEndpoint,writeRuntimeEndpointState,selectHostAdapter,getProjectStateDir,formatSkillRuntimeOverlay,createSkillRuntimeOverlay,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getDaemonRegistryPath,getProjectHash}from'@devflow-tools/sdk';import {homedir as homedir$1}from'os';import {openGlobalDevFlowDatabase,stableLearningJson}from'@devflow-tools/database';import {request as request$1}from'node:http';import {mkdirSync as mkdirSync$1,existsSync,writeFileSync as writeFileSync$1,renameSync,unlinkSync as unlinkSync$1,readFileSync as readFileSync$1,openSync as openSync$1,constants,fstatSync as fstatSync$1,closeSync as closeSync$1,readdirSync as readdirSync$1,rmSync as rmSync$1,appendFileSync,lstatSync as lstatSync$1,readSync,statSync,chmodSync,fsyncSync}from'node:fs';import {join,basename,resolve,relative,sep,dirname as dirname$1,isAbsolute}from'node:path';import {homedir}from'node:os';import {fileURLToPath}from'url';import {spawn}from'child_process';import {request}from'http';import {createRequire}from'node:module';import {prepareEmbeddingModel,MemoryGate}from'@devflow-tools/memory-engine';import {randomUUID,createHash as createHash$1}from'crypto';function Oe(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Xo=getLocalApiKey(),Pe=join(homedir(),".devflow","errors");async function C(n,e,t={}){let o=t.endpoint??resolveRuntimeEndpoint().url,r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let l;for(let u=0;u<=s;u+=1)try{return await Qo(o,n,e,r),a&®isterRuntimeHttpSuccess(o,n).transitioned&&Oe("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(p){l=p instanceof Error?p:new Error(String(p)),u<s&&await Zo(Math.min(100*2**u,1e3));}if(!l)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return Ft(n,l),{delivered:false,suppressed:false,fallbackReason:l.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(Ft(n,l),Oe("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function Qo(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,l=u=>{c||(c=true,u?i(u):r());},d=request$1({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Xo,"Content-Length":Buffer.byteLength(s)},timeout:o},u=>{u.on("error",l),u.on("end",()=>{let p=u.statusCode??0;l(p>=200&&p<300?void 0:new Error(`HTTP ${p}`));}),u.resume();});d.on("error",l),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function Ft(n,e){try{existsSync(Pe)||mkdirSync$1(Pe,{recursive:!0}),appendFileSync(join(Pe,"http-errors.log"),`${new Date().toISOString()} | ${n} | ${e.message}
|
|
2
|
+
`);}catch{}}function Zo(n){return new Promise(e=>setTimeout(e,n))}var Wt=1e4,rr=3e4,ne=500,P=class{constructor(e){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=e?.apiUrl,this.cacheDir=e?.cacheDir??join$1(process.env.DEVFLOW_STATE_DIR??join$1(homedir$1(),".devflow","global"),"telemetry-cache"),this.legacyCacheDir=e?.legacyCacheDir??(e?.cacheDir?null:join$1(homedir$1(),".devflow","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,o,r,i=process.env.CLAUDE_PROJECT_DIR??process.cwd(),s=[]){let a={executionId:e,sessionId:t,skillName:o,startedAt:r,projectRoot:i,requiredMcpTools:s};this.commitOrCache("execution_start",a)&&this.postHttp("/api/telemetry/skill-execution/start",a);}async sendExecutionComplete(e,t="completed",o=Date.now(),r){let i={executionId:e,status:t,finishedAt:o,metadata:r},s=this.commitOrCache("execution_complete",i);return s&&this.postHttp("/api/telemetry/skill-execution/complete-reconciled",i),s}async sendSessionStart(e,t,o){let r={id:e,projectRoot:t,startedAt:o,label:t.split("/").pop()??"unknown"},i=this.commitOrCache("session_start",r);return i&&this.postHttp("/api/telemetry/sessions",r),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 o={sessionId:e,finishedAt:t},r=this.commitOrCache("session_end",o);return r&&(this.getDatabase().aggregatePendingToolMetrics(),this.postHttp(`/api/telemetry/sessions/${encodeURIComponent(e)}/close`,{finishedAt:t})),r}async flushCache(){try{let o=this.getDatabase(),r=o.listTelemetryFailures({unresolvedOnly:!0,limit:ne}).reverse();for(let i of r)try{this.applyOperation(i.operation,i.payload),o.resolveTelemetryFailure(i.id);}catch{}o.trimTelemetryFailures(ne);}catch{}let t=[...new Set([this.cacheDir,this.legacyCacheDir].filter(o=>!!o))].filter(o=>existsSync$1(o)).flatMap(o=>readdirSync(o).filter(r=>r.endsWith(".json")).map(r=>{let i=join$1(o,r);try{return {cacheFile:i,envelope:ir(JSON.parse(readFileSync(i,"utf8")),r)}}catch{return null}})).filter(o=>o!==null).sort((o,r)=>o.envelope.timestamp-r.envelope.timestamp||zt(o.envelope.operation)-zt(r.envelope.operation));for(let{cacheFile:o,envelope:r}of t)try{let i=this.getDatabase();i.insertTelemetryFailure({id:r.id,operation:r.operation,payload:r.payload,error:r.failure,createdAt:r.timestamp}),this.applyOperation(r.operation,r.payload),i.resolveTelemetryFailure(r.id),unlinkSync(o);}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(o){return this.cacheOperation(e,t,o),false}}applyOperation(e,t){let o=this.getDatabase();switch(e){case "tool_call":this.ensureParentSession(o,t),o.insertToolCallEvent(t);return;case "execution_start":this.ensureParentSession(o,t),o.insertSkillExecution({executionId:t.executionId,sessionId:t.sessionId,skillName:t.skillName,startedAt:t.startedAt,status:"running",requiredMcpTools:t.requiredMcpTools});return;case "execution_complete":o.reconcileSkillExecution(t.executionId,t.status,t.finishedAt,t.metadata);return;case "session_start":o.ensureSession(t),o.insertRun({id:qt(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(!o.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":o.closeSession(t.sessionId,t.finishedAt),o.updateRun(qt(t.sessionId),{status:"completed",finishedAt:t.finishedAt});return}}ensureParentSession(e,t){let o=typeof t.sessionId=="string"?t.sessionId.trim():"";if(!o)throw new Error("Canonical session ID is required for telemetry");let r=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:o,projectRoot:r,label:r==="unknown"?void 0:r.split("/").pop(),startedAt:Number(t.startedAt??t.timestamp??Date.now())});}cacheOperation(e,t,o){let r=Date.now(),i={id:`failure:${r}:${Math.random().toString(36).slice(2,11)}`,operation:e,payload:t,failure:o instanceof Error?o.message:String(o),timestamp:r};try{let s=this.getDatabase();s.insertTelemetryFailure({id:i.id,operation:e,payload:t,error:i.failure,createdAt:r}),s.trimTelemetryFailures(ne),this.scheduleRetry();return}catch{}try{existsSync$1(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let s=join$1(this.cacheDir,`${r}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(s,JSON.stringify(i,null,2),{mode:384}),this.trimCompatibilityCache(),this.scheduleRetry();}catch{}}trimCompatibilityCache(){try{let e=readdirSync(this.cacheDir).filter(t=>t.endsWith(".json")).sort();for(let t of e.slice(0,Math.max(0,e.length-ne)))unlinkSync(join$1(this.cacheDir,t));}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache();},rr).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){C(e,t,{endpoint:this.apiUrl,fallbackReason:"telemetry_already_committed_locally"});}truncateInput(e){let t=JSON.stringify(e);return t===void 0||t.length<=Wt?e:{_truncated:true,_original_size:t.length,_preview:`${t.substring(0,Wt)}...`}}};function zt(n){return ["session_start","execution_start","tool_call","complete_event","execution_complete","session_end"].indexOf(n)}function qt(n){return `hook-run:${n}`}function ir(n,e){if(!n||typeof n!="object")throw new Error("Invalid telemetry cache envelope");let t=n;if(typeof t.operation=="string"&&t.payload!==void 0)return t;let o=t.type==="tool_call"?"tool_call":t.type==="execution_start"?"execution_start":null;if(!o)throw new Error("Unknown legacy telemetry cache operation");let r=t.payload??{},i=Number(r.timestamp??r.startedAt??Date.now());return {id:`legacy-cache:${e}`,operation:o,payload:r,failure:"Replayed legacy HTTP-first telemetry cache entry",timestamp:i}}function oe(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function E(n){return process.env.DEVFLOW_STATE_DIR??getProjectStateDir(oe(n))}var ur=2,pr=1;function mr(){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 Jt(n=mr()){let e=[join$1(n,"dist","command-registry.json"),join$1(n,"command-registry.json")];for(let t of e)try{if(!existsSync$1(t))continue;let o=JSON.parse(readFileSync(t,"utf8"));if(o.version!==ur&&o.version!==pr||!fr(o.commands)){console.error(`[devflow] command registry contract mismatch: ${t}`);continue}return o.commands}catch(o){console.error(`[devflow] command registry load failed: ${o.message}`);}return null}function fr(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 je(t.mcpTools)&&je(t.blockedNative)&&(t.source===void 0||t.source==="core"||t.source==="plugin")&&(t.requiresContext===void 0||typeof t.requiresContext=="boolean")&&(t.runtimePackages===void 0||je(t.runtimePackages))&&(t.evidenceMode===void 0||["static","runtime","mixed"].includes(t.evidenceMode))})}function je(n){return Array.isArray(n)&&n.every(e=>typeof e=="string"&&e.length>0)}function Gt(n){let e=Jt();return e?e[n]?.mcpTools??[]:[]}function Bt(n,e,t){return formatSkillRuntimeOverlay(createSkillRuntimeOverlay(n,e,{prompt:t}))}var $e=join$1(homedir$1(),".devflow"),Ne=join$1($e,"server-refs.json"),Ir=600*1e3,Er=500;function xr(){existsSync$1($e)||mkdirSync($e,{recursive:true});}function re(){try{if(existsSync$1(Ne))return JSON.parse(readFileSync(Ne,"utf-8"))}catch{}return {sessions:[],lastActivity:0}}function Kt(n){xr(),writeFileSync(Ne,JSON.stringify(n));}var se=class{constructor(e){this.process=null;this.idleTimer=null;this.onShutdown=null;this.ownerToken=null;this.projectRoot=e;}setOnShutdown(e){this.onShutdown=e;}addRef(e){let t=re();t.sessions.includes(e)||t.sessions.push(e),t.lastActivity=Date.now(),Kt(t),this.resetIdleTimer();}removeRef(e){let t=re();t.sessions=t.sessions.filter(o=>o!==e),t.lastActivity=Date.now(),Kt(t),t.sessions.length===0&&this.resetIdleTimer();}get activeSessions(){return re().sessions.length}async ensureRunning(){return await this.healthCheck()?true:(await this.startServer(),this.waitForReady())}get isRunning(){return this.process!==null&&!this.process.killed}async stop(){if(this.idleTimer&&clearTimeout(this.idleTimer),this.process){this.process.kill("SIGTERM"),await new Promise(t=>{let o=setTimeout(()=>{this.process&&!this.process.killed&&this.process.kill("SIGKILL"),t();},5e3);this.process?this.process.on("exit",()=>{clearTimeout(o),t();}):(clearTimeout(o),t());}),this.process=null;let e=readRuntimeEndpointState();e&&e.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped");}}async startServer(){let e=Mr(this.projectRoot);this.ownerToken=randomUUID$1();let t=resolveRuntimeEndpoint();this.process=spawn(process.execPath,[e,"--devflow-instance-token",this.ownerToken],{cwd:this.projectRoot,env:{...process.env,NODE_ENV:process.env.NODE_ENV||"development"},stdio:["ignore","pipe","pipe"]}),writeRuntimeEndpointState({url:t.url,port:t.port,pid:this.process.pid??0,ownerToken:this.ownerToken,status:"launching"}),this.process.stdout?.on("data",o=>{}),this.process.stderr?.on("data",o=>{}),this.process.on("exit",o=>{let r=readRuntimeEndpointState();r&&r.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("stopped"),this.process=null,this.onShutdown&&this.onShutdown();}),this.process.on("error",()=>{let o=readRuntimeEndpointState();o&&o.ownerToken===this.ownerToken&&updateRuntimeEndpointStatus("degraded"),this.process=null;});}async waitForReady(){let e=Date.now()+3e4;for(;Date.now()<e;){if(await this.healthCheck())return true;await new Promise(t=>setTimeout(t,Er));}return false}healthCheck(){return new Promise(e=>{let t=resolveRuntimeEndpoint(),o=new URL("/api/health",t.url),r=request({hostname:o.hostname,port:o.port,path:o.pathname,method:"GET",timeout:2e3},i=>{let s=i.statusCode===200;s&&readRuntimeEndpointState()&&updateRuntimeEndpointStatus("healthy"),i.resume(),e(s);});r.on("error",()=>e(false)),r.on("timeout",()=>{r.destroy(),e(false);}),r.end();})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),!(re().sessions.length>0)&&(this.idleTimer=setTimeout(()=>{this.stop();},Ir).unref());}};function Mr(n){let e=createRequire(import.meta.url),t=[()=>e.resolve("@devflow-tools/server/dist/main.js"),()=>join$1(n,"node_modules","@devflow-tools","server","dist","main.js"),()=>join$1(n,"apps","server","dist","main.js")];for(let o of t)try{let r=o();if(existsSync$1(r))return r}catch{}throw new Error("DevFlow server entry point is not installed or built")}function ae(n){if(!n||typeof n!="object"||Array.isArray(n))return {};let e=n,t={};for(let o of ["lastMcpCall","bypassCount"])if(o in e){let r=e[o];if(r==null)continue;t[o]=typeof r=="number"&&Number.isFinite(r)&&r>=0?r:0;}return t}function Dr(n,e){return n.lastMcpCall===e.lastMcpCall&&n.bypassCount===e.bypassCount}function Ar(n){try{return existsSync$1(n)?ae(JSON.parse(readFileSync(n,"utf-8"))):{}}catch{return {}}}function Or(n,e){let t=e instanceof Error?e.message:String(e);console.error(`[devflow] Receipt ${n} skipped: ${t}`);}function Vt(n){let e=E(n);for(let t of ["receipt.json","receipt-lock.sqlite","receipt-lock.sqlite-shm","receipt-lock.sqlite-wal"])try{existsSync$1(join$1(e,t))&&unlinkSync(join$1(e,t));}catch{}}function Pr(n,e){if(n.getHookReceipt(e)){Vt(e);return}let t=join$1(E(e),"receipt.json");if(!existsSync$1(t))return;let o=Ar(t);n.updateHookReceipt(e,()=>o),Vt(e);}function Qt(n,e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),Pr(o,n);let r={},i=o.updateHookReceipt(n,a=>(r=ae(a),ae(e(r)))),s=ae(i);return {receipt:s,applied:!0,changed:!Dr(r,s)}}catch(r){return Or(t,r),{receipt:{},applied:false,changed:false}}finally{try{o?.close();}catch{}}}function ce(n,e){return Qt(n,()=>e,"write").applied}function We(n,e){return Qt(n,e,"update")}var Yt={Grep:"get_project_context",Glob:"get_project_context",Agent:"get_project_context",Bash:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function jr(n){switch(n){case "WebSearch":case "WebFetch":return 1;case "Agent":return 3;case "Grep":case "Glob":return 3;case "Bash":return 5;default:return 2}}var G=class{constructor(e,t,o){this.projectRoot=e;this.sessionId=t;this.executionId=o;}getPhase(){if(!this.sessionId||!this.executionId)return "idle";let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});let t=e.getContextReceipt(this.projectRoot,this.sessionId,this.executionId);if(t&&t.expiresAt>Date.now())return "context_ready";t&&e.deleteContextReceipt(this.projectRoot,this.sessionId,this.executionId);}catch{}finally{try{e?.close();}catch{}}return "context_gathering"}evaluate(e,t){let o=this.getPhase();if(t||e==="Skill")return {permissionDecision:"allow"};if(o==="context_gathering"&&Yt[e])return {permissionDecision:"deny",reason:`DevFlow context required. Call mcp__devflow__get_project_context, then retry ${e}.`};if(o==="context_ready")return {permissionDecision:"allow"};let r=Yt[e];if(!r)return {permissionDecision:"allow"};let i=We(this.projectRoot,c=>({...c,bypassCount:(c.bypassCount??0)+1}));if(!i.applied)return {permissionDecision:"allow"};let s=i.receipt.bypassCount??0,a=jr(e);return s>=a?{permissionDecision:"allow",additionalContext:`\u5DF2 ${s} \u6B21\u76F4\u63A5\u4F7F\u7528 ${e}\uFF0C\u5EFA\u8BAE\u7528 mcp__devflow__${r} \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`}:{permissionDecision:"allow"}}recordMcpCall(){ce(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});}};var Ur=10,Wr=5e3,zr=3e4,qr=new Int32Array(new SharedArrayBuffer(4)),rn=0;function Jr(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.rootPath=="string"&&e.rootPath.length>0&&typeof e.projectHash=="string"&&e.projectHash.length>0&&typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.startedAt=="number"&&Number.isFinite(e.startedAt)&&e.startedAt>=0}function sn(n){if(!existsSync(n))return {entries:[],needsRepair:false};try{let e=JSON.parse(readFileSync$1(n,"utf8"));if(!Array.isArray(e))return {entries:[],needsRepair:!0};let t=e.filter(Jr);return {entries:t,needsRepair:t.length!==e.length}}catch{return {entries:[],needsRepair:true}}}function an(n,e){mkdirSync$1(dirname$1(n),{recursive:true});let t=`${n}.${process.pid}.${Date.now()}.${rn++}.tmp`,o;try{o=openSync$1(t,"wx"),writeFileSync$1(o,JSON.stringify(e,null,2)),closeSync$1(o),o=void 0,renameSync(t,n);}finally{try{o!==void 0&&closeSync$1(o);}finally{rmSync$1(t,{force:true});}}}function cn(n){try{return process.kill(n,0),!0}catch(e){return e.code!=="ESRCH"}}function ln(n){if(typeof n!="object"||n===null)return false;let e=n;return typeof e.pid=="number"&&Number.isInteger(e.pid)&&e.pid>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function Zt(n,e){try{return readFileSync$1(n,"utf8")!==e?!1:(rmSync$1(n),!0)}catch(t){return t.code==="ENOENT"}}function Gr(n){try{let e=readFileSync$1(n,"utf8"),t;try{let r=JSON.parse(e);ln(r)&&(t=r);}catch{}return t?cn(t.pid)?!1:Zt(n,e):Date.now()-statSync(n).mtimeMs>zr&&Zt(n,e)}catch(e){return e.code==="ENOENT"}}function Br(n){mkdirSync$1(dirname$1(n),{recursive:true});let e=`${n}.lock`,t=Date.now()+Wr;for(;;){let o=`${process.pid}:${Date.now()}:${rn++}`,r;try{return r=openSync$1(e,"wx"),writeFileSync$1(r,JSON.stringify({pid:process.pid,createdAt:Date.now(),token:o})),closeSync$1(r),r=void 0,{path:e,token:o}}catch(i){if(r!==void 0)try{closeSync$1(r);}finally{rmSync$1(e,{force:true});}if(i.code!=="EEXIST")throw i}if(!Gr(e)){if(Date.now()>=t)throw new Error(`Timed out acquiring daemon registry lock: ${e}`);Atomics.wait(qr,0,0,Ur);}}}function Kr(n){try{let e=readFileSync$1(n.path,"utf8"),t=JSON.parse(e);ln(t)&&t.token===n.token&&rmSync$1(n.path);}catch(e){if(e.code!=="ENOENT")throw e}}function dn(n){let e=getDaemonRegistryPath(),t=Br(e);try{return n(e)}finally{Kr(t);}}function un(n,e){dn(t=>{let o=sn(t).entries.filter(r=>r.rootPath!==n&&cn(r.pid));o.push({rootPath:n,projectHash:getProjectHash(n),pid:e,startedAt:Date.now()}),an(t,o);});}function pn(n,e){dn(t=>{let o=sn(t).entries.filter(r=>r.rootPath!==n||e!==void 0&&r.pid!==e);an(t,o);});}async function B(n){let e=!n.memory,t=n.memory??new MemoryGate(n.projectRoot),o=0,r=0;try{await t.forceWarmUp(),n.trigger==="session_end"&&(o=await t.releasePendingDistillLeases(n.sessionId)),r=t.getPendingEventCount(n.sessionId,n.trigger!=="session_end");}finally{e&&t.close();}let i={pendingEvents:r,releasedLeases:o,trigger:n.trigger,sessionId:n.sessionId,details:n.details};try{let s=openGlobalDevFlowDatabase();try{let a=Date.now(),c=n.trigger==="session_end"&&n.sessionId?`distill:session_end:${createHash("sha256").update(`${n.projectRoot}\0${n.sessionId}`).digest("hex").slice(0,24)}`:`distill:${a}:${Math.random().toString(36).slice(2,10)}`;s.recordMemoryDistillCheckpoint({id:c,projectRoot:n.projectRoot,sessionId:n.sessionId,trigger:n.trigger,pendingEvents:r,releasedLeases:o,details:n.details,createdAt:a}),s.insertEvent({kind:"memory_distill_requested",timestamp:a,success:!0,metadata:{...i,projectRoot:n.projectRoot}});}finally{s.close();}}catch(s){if(n.strictPersistence)throw s}return i}function mn(n){if(n.pendingEvents===0)return "";let e=n.sessionId?`\uFF0CsessionId=${n.sessionId}`:"";return `Memory distill checkpoint: ${n.pendingEvents} \u4E2A\u4E8B\u4EF6\u5F85\u63D0\u70BC${e}\u3002\u4E0A\u4E0B\u6587\u538B\u7F29\u5B8C\u6210\u540E\uFF0C\u8C03\u7528 mcp__devflow__memory_request_distill\uFF1B\u6309\u8FD4\u56DE\u7684 nextPage \u5206\u9875\u8BFB\u53D6\u5168\u90E8\u4E8B\u4EF6\uFF0C\u63D0\u70BC observations\uFF0C\u518D\u8C03\u7528 mcp__devflow__memory_save_distilled \u5E76\u786E\u8BA4\u4FDD\u5B58\u7ED3\u679C\u3002`}function yn(n){return Buffer.from(n,"utf8").toString("base64url")}function ti(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function kn(n){return `${n}:legacy-journal`}var M=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(E(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=vn(i.evidenceObligations),i.evidenceDegradations=bn(i.evidenceDegradations),i.evidenceOutcomes=wn(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(l=>l.contractId===t.id))?.obligationId??ti(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(l=>l.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let l=s.evidenceObligations.find(d=>d.obligationId===t);return l?structuredClone(l):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${yn(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",yn(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=vn(e.evidenceObligations),e.evidenceDegradations=bn(e.evidenceDegradations),e.evidenceOutcomes=wn(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=ni(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||Sn(i.kind)-Sn(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??0;e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),!o&&(t.kind==="degrade"&&e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i}),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),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function vn(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)||!Rn(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:kn(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function bn(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 wn(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 ni(n){if(!n||typeof n!="object")return null;let e=n;if(!["add","correction","resolve","degrade"].includes(e.kind??"")||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let t=typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:kn(e.contractId);if(e.kind==="add")return Rn(e.contract)?{...e,obligationId:t}:null;if(e.kind==="correction"){let o=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof o=="string"&&/^[a-f0-9]{64}$/.test(o)&&Array.isArray(e.violations)&&e.violations.every(r=>typeof r=="string"&&r.length<=240)?{...e,obligationId:t,fingerprint:o}:null}return e.kind==="resolve"?{...e,obligationId:t}:typeof e.reason=="string"&&e.reason.length<=240?{...e,obligationId:t}:null}function Sn(n){return n==="add"?0:n==="correction"?1:2}function Rn(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function xn(n,e){let t=Dn(n);mkdirSync$1(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync$1(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync$1(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function Mn(n){let e=Dn(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.receiptId!="string"||typeof s.inputJson!="string"||typeof s.sessionId!="string"||typeof s.cleanupSharedState!="boolean")throw unlinkSync$1(i),new Error("session_finalize_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Tn(n){unlinkSync$1(n.path);}function Cn(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function Dn(n){return join(E(n),"session-finalize-pending")}var mi=256*1024,fi=48*1024,hi=512*1024,gi=500,yi=5,K=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function vi(n){return n==="react_audit_performance"||n.endsWith("__react_audit_performance")}function bi(n){let e=V(n,0,new Set);return e?Ci(e.contract,e.canonicalReport):null}function Pn(n){if(!n.sessionId||!vi(n.toolName))return null;let e=bi(n.toolResponse);if(!e)return null;let t=Date.now(),o=n.runtimeStore.addEvidenceObligation(n.sessionId,e,t,n.toolUseId),r=n.runtimeStore.get(n.sessionId);if(o&&r){let i=openGlobalDevFlowDatabase();try{i.upsertSessionObligation({obligationId:`evidence:${o.obligationId}`,projectRoot:r.projectRoot,sessionId:n.sessionId,executionId:r.executionId,kind:"evidence_contract",state:"open",payload:{contract:e,runtimeObligationId:o.obligationId},createdAt:t,updatedAt:t});}finally{i.close();}}return wi(e)}function wi(n){return [`DevFlow performance evidence contract ${n.id} is active.`,`The final performance answer MUST contain these three sections exactly: ${n.requiredSections.join(" / ")}.`,n.runtimeProfilingOccurred?"Only claims directly supported by the returned runtime measurements may be stated as measured facts.":"No runtime profiling occurred. Treat every finding as a static candidate: do not assign P0/high-risk severity, claim a confirmed bottleneck/jank/frame drop/CPU hotspot, quantify performance or benefit, or recommend requestAnimationFrame as generic throttling without sampling evidence.",`samplingEvidenceOccurred=${n.samplingEvidenceOccurred}. RAF recommendations are permitted only when this structured contract field is true; answer text cannot self-declare sampling evidence.`,"Use the canonical report below directly or preserve its evidence boundaries. Stop will request one correction for unsupported claims, then fail open with degradation telemetry.",n.canonicalReport].join(`
|
|
3
3
|
|
|
4
|
-
`)}function
|
|
4
|
+
`)}function jn(n){let e=n.runtimeStore??new M(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return null;let o=$n(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=_i(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a});continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved");}return i.length===0?null:Si(i)}function Si(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
`)].join(`
|
|
9
9
|
|
|
10
|
-
`)}}function
|
|
11
|
-
`)+1)));let l=c.split(/\r?\n/).slice(-
|
|
12
|
-
`):"";if(u.trim()){let d=u.trim(),p=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,g=createHash("sha256").update(d).digest("hex"),h=createHash("sha256").update(`${p}\0${g}`).digest("hex");t.push({text:d,timestamp:c,fingerprint:h});}}catch{continue}}return t}function Si(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function An(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=V.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}function Ve(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Y(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var j=class extends Error{constructor(e,t){super(`session_finalize_${e}:${t}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${e}`;}};function he(n){let e;try{e=openGlobalDevFlowDatabase();let t=(n.executionId?e.getSkillExecution(n.executionId):null)??e.getLatestSkillExecutionForSession(n.sessionId),o={stage:n.stage,reason:n.reason,degradedAt:Date.now()};t&&e.mergeSkillExecutionMetadata(t.executionId,{...n.metadata,sessionFinalizationDegradations:[o]}),e.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t?.executionId,...o}});}catch{}finally{e?.close();}}function ge(n,e=oe(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o},l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let u=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),d=l.getWorkByIdempotencyKey(a);return {status:u.state==="closed"||u.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:d?.state??"pending",closureState:u.state,pendingWorkCount:u.pendingWorkCount}}catch(u){if(!r)throw u;return wn(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}async function jn(n,e=oe(),t=true,o){let r;try{r=JSON.parse(n);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new T(e),a=s.get(i),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(g=>g.contractId)??[]},l=o?.telemetry??new O,u=!o?.telemetry,d=false,p;try{try{await l.flushAndAggregate();}catch{}let g=Date.now(),h=o?.executionId??a?.executionId,v;try{let y=openGlobalDevFlowDatabase();try{v=y.listSessionMemoryTurnsForReconciliation(e,i);for(let m of v){let b=`memory:${m.turnId}`,f=y.getSessionObligation(e,i,b);f?f.state==="open"&&m.status!=="pending"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:b,state:"satisfied",receiptId:m.receiptId,reason:m.reason,resolvedAt:m.decidedAt}):y.upsertSessionObligation({obligationId:b,projectRoot:e,sessionId:i,turnId:m.turnId,kind:"memory_decision",state:m.status==="pending"?"open":"satisfied",payload:{eventId:m.eventId,promptHash:m.promptHash},receiptId:m.receiptId,reason:m.reason,createdAt:m.createdAt,updatedAt:m.decidedAt??m.createdAt,resolvedAt:m.decidedAt});}}finally{y.close();}}catch(y){let m=Y(y),b={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"turn_load",reason:m,metadata:b}),new j("turn_load",m)}let S=Ve(v),w=o?.memory??(p=new MemoryGate(e)),R={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let y=fe(r.transcript_path),m=openGlobalDevFlowDatabase(),b="unknown",f="no_terminal_host_action_evidence",ee,te,Rt,It=[];try{let De=m.listHostActionsForSession(e,i,h),Et=De.filter(W=>W.state==="verified"),Ce=De.filter(W=>["failed","cancelled","degraded"].includes(W.state));Ce.length>0?(b="negative",f=`terminal_host_action_${Ce[0].state}`):Et.length>0&&(b="positive",f="host_action_verified");let Oe=Ce[0]??Et.at(-1);ee=Oe?.runId,te=Oe?.contextReceipt,Rt=Oe?.evidenceHash,It=De.flatMap(W=>{let xt=W.report.toolUseIds;return Array.isArray(xt)?xt.filter(Oo=>typeof Oo=="string"):[]});}finally{m.close();}let Co=await w.attributeRetrievalBenefits({sessionId:i,executionId:h,finalAnswer:y,outcome:b,outcomeReason:f,workflowRunId:ee,contextReceipt:te,toolEvidence:It,verificationReceipt:Rt});R={status:y?"evaluated":"unknown",...Co};}catch(y){R={...R,status:"degraded",reason:Y(y)};}let I;try{I=await w.reconcileDecidedTurnEventWindows(i,v,g);}catch(y){let m=Y(y),b={...S,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:m,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"event_reconciliation",reason:m,metadata:b}),new j("event_reconciliation",m)}let x;try{x=await G({projectRoot:e,sessionId:i,trigger:"session_end",memory:w,details:{eventReconciliation:I},strictPersistence:!0});}catch(y){let m=Y(y),b={...S,...c,memoryEventReconciliation:{status:"completed",...I,checkpointPending:null},memoryCheckpointDegradation:m};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"checkpoint",reason:m,metadata:b}),new j("checkpoint",m)}let U={memoryBenefitAttribution:R,memoryEventReconciliation:{status:"completed",...I,checkpointPending:x.pendingEvents},memoryDistillCheckpoint:x};try{let y=openGlobalDevFlowDatabase();try{let m=`session-finalize:${i}:events`,b=Math.max(Number(x.pendingEvents??0),Number(I.remainingUndecided??0)),f=y.getSessionObligation(e,i,m);b>0?y.upsertSessionObligation({obligationId:m,projectRoot:e,sessionId:i,executionId:h,kind:"session_finalize",state:"open",payload:{pendingEvents:b,reconciliation:I,checkpointId:x.id},reason:"active_unprocessed_session_events",createdAt:f?.createdAt??g,updatedAt:g}):f?.state==="open"&&y.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:m,state:"satisfied",reason:"session_events_reconciled",resolvedAt:g});}finally{y.close();}}catch(y){console.error("[devflow] Session finalization obligation persistence failed:",y.message);}try{await w.closeSession(i),p&&(p.close(),p=void 0);}catch(y){let m=Y(y),b={...S,...c,...U,memorySessionCloseDegradation:m};throw he({projectRoot:e,sessionId:i,executionId:h,stage:"memory_close",reason:m,metadata:b}),new j("memory_close",m)}let _={...S,...c,...U};d=!0;let k;try{k=openGlobalDevFlowDatabase();let y=h;if(y)try{k.reconcileSkillExecution(y,"completed",g,_);let f=k.getSkillExecution(y);await M("/api/telemetry/skill-execution/complete",{executionId:y,finishedAt:g,status:"completed",summary:{totalToolCalls:f?.totalToolCalls??0,mcpToolCalls:f?.mcpToolCalls??0,directToolCalls:f?.directToolCalls??0,subagentCount:f?.subagentCount??0,totalDuration:f?.totalDuration??0,mcpComplianceRate:f?.mcpComplianceRate??0,missedTools:f?.missedMcpTools??[],actualFailureCount:f?.failedToolCalls??0,fallbackCount:f?.fallbackCount??0,fallbackReasons:f?.fallbackReasons??[]},metadata:_},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let m=k.reconcileRunningSkillExecutionsForSession(i,g,{closureReason:"session_finalize",..._});for(let f of m)await M("/api/telemetry/skill-execution/complete",{executionId:f.executionId,finishedAt:f.finishedAt,status:f.status,summary:{totalToolCalls:f.totalToolCalls??0,mcpToolCalls:f.mcpToolCalls??0,directToolCalls:f.directToolCalls??0,subagentCount:f.subagentCount??0,totalDuration:f.totalDuration??0,mcpComplianceRate:f.mcpComplianceRate??0,missedTools:f.missedMcpTools??[],actualFailureCount:f.failedToolCalls??0,fallbackCount:f.fallbackCount??0,fallbackReasons:f.fallbackReasons??[]},metadata:_},{fallbackReason:"skill_execution_already_reconciled_locally"});let b=k.getLatestSkillExecutionForSession(i);if(b&&!m.some(f=>f.executionId===b.executionId)&&k.mergeSkillExecutionMetadata(b.executionId,_),t){k.deleteHookReceipt(e);let f=E(e),ee=createHash("sha256").update(e).digest("hex").slice(0,12);for(let te of [`session-id-${ee}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(f,te),{force:!0});}k.deleteContextReceipt(e,i);}catch{}finally{k?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch{}}finally{if(p)try{p.close();}catch{}u&&l.close(),d&&s.removeSession(i);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=ge(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var Di=/^\/(?:devflow:)?[\w-]+\b\s*/iu,Ci=/\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,Oi=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Ai=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function ye(n){let e=n.trim().replace(Di,"").trim();return !e||Ci.test(e)?null:(Ai.exec(e)??Oi.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Pi(n){let e=createHash("sha256").update(n).digest("hex").slice(0,16),t=process.env.DEVFLOW_STATE_DIR||join(homedir(),".devflow","state",e);return join(t,"memory-intents.jsonl")}function ji(n){try{return readFileSync$1(n,"utf8").split(`
|
|
13
|
-
`).filter(Boolean).flatMap(e=>{try{let t=JSON.parse(e);return typeof t.content=="string"&&typeof t.createdAt=="number"?[t]:[]}catch{return []}})}catch{return []}}function
|
|
10
|
+
`)}}function _i(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=Fn(n.split(/\r?\n/)),i=Nn(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let l=r.claimLines[c].trim();if(!l||Ri(l))continue;let d=i.byLine.get(c);for(let u of Ti(l))Ei(u,d,a,t);}return [...t]}function Fn(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>ki(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function ki(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function Ri(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?Ii(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function Ii(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function Ei(n,e,t,o){let r=/\bP0\b/gi;for(let y of n.matchAll(r))On(n,y.index??0,y[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))On(n,y.index??0,y[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))Mi(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),l=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||l)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),u=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!u&&o.add("unsupported_benefit_percentage"),d&&!u&&o.add("unsupported_performance_number");let p=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),m=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);p&&h&&!m&&!t&&o.add("raf_without_sampling_evidence");}function On(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=xi(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function xi(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function Mi(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function Ti(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function V(n,e,t){if(e>yi||n===null||n===void 0)return null;if(typeof n=="string"){if(Buffer.byteLength(n,"utf8")>mi)return null;try{return V(JSON.parse(n),e+1,t)}catch{return null}}if(typeof n!="object"||t.has(n))return null;if(t.add(n),Array.isArray(n)){for(let r of n.slice(0,16)){let i=V(r,e+1,t);if(i)return i}return null}let o=n;if("evidenceContract"in o)return {contract:o.evidenceContract,canonicalReport:o.canonicalReport};for(let r of ["structuredContent","data","result"])if(r in o){let i=V(o[r],e+1,t);if(i)return i}if(Array.isArray(o.content))for(let r of o.content.slice(0,16)){let i=r&&typeof r=="object"&&"text"in r?r.text:r,s=V(i,e+1,t);if(s)return s}return null}function Ci(n,e){if(!n||typeof n!="object"||Array.isArray(n))return null;let t=n;if(t.version!=="1.0"||typeof t.id!="string"||!/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(t.id)||typeof t.runtimeProfilingOccurred!="boolean"||typeof t.samplingEvidenceOccurred!="boolean"||!Array.isArray(t.requiredSections)||t.requiredSections.length!==K.length)return null;let o=t.requiredSections.filter(c=>typeof c=="string");if(o.length!==K.length||K.some((c,l)=>o[l]!==c)||!Array.isArray(t.prohibitedClaims)||t.prohibitedClaims.length>16)return null;let r=t.prohibitedClaims.filter(c=>typeof c=="string"&&c.length<=128);if(r.length!==t.prohibitedClaims.length)return null;let i=t.correctionPolicy;if(!i||typeof i!="object"||Array.isArray(i))return null;let s=i;if(s.maxAttempts!==1||s.repeatedViolation!=="fail_open")return null;let a=typeof t.canonicalReport=="string"?t.canonicalReport:e;return typeof a!="string"||Buffer.byteLength(a,"utf8")>fi||K.some(c=>!a.includes(c))?null:{version:"1.0",id:t.id,runtimeProfilingOccurred:t.runtimeProfilingOccurred,samplingEvidenceOccurred:t.samplingEvidenceOccurred,requiredSections:o,prohibitedClaims:r,correctionPolicy:{maxAttempts:1,repeatedViolation:"fail_open"},canonicalReport:a}}function $n(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync$1(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync$1(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync$1(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,hi),s=Buffer.alloc(i),a=0;for(;a<i;){let m=readSync(t,s,a,i-a,r.size-i+a);if(m===0)break;a+=m;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
|
|
11
|
+
`)+1)));let l=c.split(/\r?\n/).slice(-gi),d=e.length>0?Math.min(...e.map(m=>m.promptedAt)):0,u=Ai(l,d),h=[...u].reverse().find(m=>Di(m.text,e))??u.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync$1(t);}}function Di(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=Nn(Fn(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function fe(n){return $n(n,[]).answer}function Ai(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=Oi(i.timestamp);if(c>0&&c+5e3<e)continue;let l=s.content,d=typeof l=="string"?l:Array.isArray(l)?l.filter(u=>u&&typeof u=="object"&&u.type==="text").map(u=>u.text).filter(u=>typeof u=="string").join(`
|
|
12
|
+
`):"";if(d.trim()){let u=d.trim(),p=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(u).digest("hex"),m=createHash("sha256").update(`${p}\0${h}`).digest("hex");t.push({text:u,timestamp:c,fingerprint:m});}}catch{continue}}return t}function Oi(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function Nn(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=K.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}function Ke(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Y(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}var $=class extends Error{constructor(e,t){super(`session_finalize_${e}:${t}`),this.name="SessionFinalizationRetryableError",this.category=`session_finalize_${e}`;}};function he(n){let e;try{e=openGlobalDevFlowDatabase();let t=(n.executionId?e.getSkillExecution(n.executionId):null)??e.getLatestSkillExecutionForSession(n.sessionId),o={stage:n.stage,reason:n.reason,degradedAt:Date.now()};t&&e.mergeSkillExecutionMetadata(t.executionId,{...n.metadata,sessionFinalizationDegradations:[o]}),e.insertEvent({kind:"session_finalize_degraded",timestamp:o.degradedAt,success:!1,metadata:{projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t?.executionId,...o}});}catch{}finally{e?.close();}}function ge(n,e=oe(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o},l;try{l=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=l.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),u=l.getWorkByIdempotencyKey(a);return {status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:u?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount}}catch(d){if(!r)throw d;return xn(e,{receiptId:a,...c}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{l?.close();}}async function Hn(n,e=oe(),t=true,o){let r;try{r=JSON.parse(n);}catch{return}let i=r.session_id?.trim();if(!i)return;let s=new M(e),a=s.get(i),c={evidenceDegradations:a?.evidenceDegradations??[],evidenceContractOutcomes:a?.evidenceOutcomes??[],pendingEvidenceContractIds:a?.evidenceObligations.map(h=>h.contractId)??[]},l=o?.telemetry??new P,d=!o?.telemetry,u=false,p;try{try{await l.flushAndAggregate();}catch{}let h=Date.now(),m=o?.executionId??a?.executionId,y;try{let v=openGlobalDevFlowDatabase();try{y=v.listSessionMemoryTurnsForReconciliation(e,i);for(let f of y){let w=`memory:${f.turnId}`,g=v.getSessionObligation(e,i,w);g?g.state==="open"&&f.status!=="pending"&&v.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:w,state:"satisfied",receiptId:f.receiptId,reason:f.reason,resolvedAt:f.decidedAt}):v.upsertSessionObligation({obligationId:w,projectRoot:e,sessionId:i,turnId:f.turnId,kind:"memory_decision",state:f.status==="pending"?"open":"satisfied",payload:{eventId:f.eventId,promptHash:f.promptHash},receiptId:f.receiptId,reason:f.reason,createdAt:f.createdAt,updatedAt:f.decidedAt??f.createdAt,resolvedAt:f.decidedAt});}}finally{v.close();}}catch(v){let f=Y(v),w={...c,memoryEventReconciliation:{status:"degraded",stage:"turn_load",reason:f,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:m,stage:"turn_load",reason:f,metadata:w}),new $("turn_load",f)}let b=Ke(y),_=o?.memory??(p=new MemoryGate(e)),S={status:"unknown",selected:0,adopted:0,unknown:0,positive:0,negative:0};try{let v=fe(r.transcript_path),f=openGlobalDevFlowDatabase(),w="unknown",g="no_terminal_host_action_evidence",ee,te,Mt,Tt=[];try{let Ce=f.listHostActionsForSession(e,i,m),Ct=Ce.filter(W=>W.state==="verified"),De=Ce.filter(W=>["failed","cancelled","degraded"].includes(W.state));De.length>0?(w="negative",g=`terminal_host_action_${De[0].state}`):Ct.length>0&&(w="positive",g="host_action_verified");let Ae=De[0]??Ct.at(-1);ee=Ae?.runId,te=Ae?.contextReceipt,Mt=Ae?.evidenceHash,Tt=Ce.flatMap(W=>{let Dt=W.report.toolUseIds;return Array.isArray(Dt)?Dt.filter(zo=>typeof zo=="string"):[]});}finally{f.close();}let Wo=await _.attributeRetrievalBenefits({sessionId:i,executionId:m,finalAnswer:v,outcome:w,outcomeReason:g,workflowRunId:ee,contextReceipt:te,toolEvidence:Tt,verificationReceipt:Mt});S={status:v?"evaluated":"unknown",...Wo};}catch(v){S={...S,status:"degraded",reason:Y(v)};}let I;try{I=await _.reconcileDecidedTurnEventWindows(i,y,h);}catch(v){let f=Y(v),w={...b,...c,memoryEventReconciliation:{status:"degraded",stage:"event_reconciliation",reason:f,committedProcessed:0,skippedDiscarded:0,remainingUndecided:null,checkpointPending:null}};throw he({projectRoot:e,sessionId:i,executionId:m,stage:"event_reconciliation",reason:f,metadata:w}),new $("event_reconciliation",f)}let x;try{x=await B({projectRoot:e,sessionId:i,trigger:"session_end",memory:_,details:{eventReconciliation:I},strictPersistence:!0});}catch(v){let f=Y(v),w={...b,...c,memoryEventReconciliation:{status:"completed",...I,checkpointPending:null},memoryCheckpointDegradation:f};throw he({projectRoot:e,sessionId:i,executionId:m,stage:"checkpoint",reason:f,metadata:w}),new $("checkpoint",f)}let U={memoryBenefitAttribution:S,memoryEventReconciliation:{status:"completed",...I,checkpointPending:x.pendingEvents},memoryDistillCheckpoint:x};try{let v=openGlobalDevFlowDatabase();try{let f=`session-finalize:${i}:events`,w=Math.max(Number(x.pendingEvents??0),Number(I.remainingUndecided??0)),g=v.getSessionObligation(e,i,f);w>0?v.upsertSessionObligation({obligationId:f,projectRoot:e,sessionId:i,executionId:m,kind:"session_finalize",state:"open",payload:{pendingEvents:w,reconciliation:I,checkpointId:x.id},reason:"active_unprocessed_session_events",createdAt:g?.createdAt??h,updatedAt:h}):g?.state==="open"&&v.resolveSessionObligation({projectRoot:e,sessionId:i,obligationId:f,state:"satisfied",reason:"session_events_reconciled",resolvedAt:h});}finally{v.close();}}catch(v){console.error("[devflow] Session finalization obligation persistence failed:",v.message);}try{await _.closeSession(i),p&&(p.close(),p=void 0);}catch(v){let f=Y(v),w={...b,...c,...U,memorySessionCloseDegradation:f};throw he({projectRoot:e,sessionId:i,executionId:m,stage:"memory_close",reason:f,metadata:w}),new $("memory_close",f)}let k={...b,...c,...U};u=!0;let R;try{R=openGlobalDevFlowDatabase();let v=m;if(v)try{R.reconcileSkillExecution(v,"completed",h,k);let g=R.getSkillExecution(v);await C("/api/telemetry/skill-execution/complete",{executionId:v,finishedAt:h,status:"completed",summary:{totalToolCalls:g?.totalToolCalls??0,mcpToolCalls:g?.mcpToolCalls??0,directToolCalls:g?.directToolCalls??0,subagentCount:g?.subagentCount??0,totalDuration:g?.totalDuration??0,mcpComplianceRate:g?.mcpComplianceRate??0,missedTools:g?.missedMcpTools??[],actualFailureCount:g?.failedToolCalls??0,fallbackCount:g?.fallbackCount??0,fallbackReasons:g?.fallbackReasons??[]},metadata:k},{fallbackReason:"skill_execution_already_reconciled_locally"});}catch{}let f=R.reconcileRunningSkillExecutionsForSession(i,h,{closureReason:"session_finalize",...k});for(let g of f)await C("/api/telemetry/skill-execution/complete",{executionId:g.executionId,finishedAt:g.finishedAt,status:g.status,summary:{totalToolCalls:g.totalToolCalls??0,mcpToolCalls:g.mcpToolCalls??0,directToolCalls:g.directToolCalls??0,subagentCount:g.subagentCount??0,totalDuration:g.totalDuration??0,mcpComplianceRate:g.mcpComplianceRate??0,missedTools:g.missedMcpTools??[],actualFailureCount:g.failedToolCalls??0,fallbackCount:g.fallbackCount??0,fallbackReasons:g.fallbackReasons??[]},metadata:k},{fallbackReason:"skill_execution_already_reconciled_locally"});let w=R.getLatestSkillExecutionForSession(i);if(w&&!f.some(g=>g.executionId===w.executionId)&&R.mergeSkillExecutionMetadata(w.executionId,k),t){R.deleteHookReceipt(e);let g=E(e),ee=createHash("sha256").update(e).digest("hex").slice(0,12);for(let te of [`session-id-${ee}`,"current-execution-id","current-skill.json","event-map.json"])rmSync$1(join(g,te),{force:!0});}R.deleteContextReceipt(e,i);}catch{}finally{R?.close();}try{await l.endSession(i),await l.flushAndAggregate();}catch{}}finally{if(p)try{p.close();}catch{}d&&l.close(),u&&s.removeSession(i);}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=ge(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var zi=/^\/(?:devflow:)?[\w-]+\b\s*/iu,qi=/\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,Ji=/(?:^|[.!?]\s*)(?:(?:please|kindly)\s+)?(?:remember|memorize|save\s+this|store\s+this|note\s+that)(?:\s+(?:that|to))?[\s:,-]*(.+)$/iu,Gi=/(?:^|[。!?;,,]\s*)(?:(?:请|麻烦|务必|一定要|帮我|帮忙|需要)\s*)?(?:记住|记一下|记下来|记|记录一下|记录下来|保存一下|保存下来)(?:这(?:件事|一点|个信息|些内容))?[\s::,,]*(.+)$/iu;function ye(n){let e=n.trim().replace(zi,"").trim();return !e||qi.test(e)?null:(Gi.exec(e)??Ji.exec(e))?.[1]?.trim().replace(/^[::,,\s]+/u,"")||null}function Bi(n){let e=createHash("sha256").update(n).digest("hex").slice(0,16),t=process.env.DEVFLOW_STATE_DIR||join(homedir(),".devflow","state",e);return join(t,"memory-intents.jsonl")}function Ki(n){try{return readFileSync$1(n,"utf8").split(`
|
|
13
|
+
`).filter(Boolean).flatMap(e=>{try{let t=JSON.parse(e);return typeof t.content=="string"&&typeof t.createdAt=="number"?[t]:[]}catch{return []}})}catch{return []}}function qn(n){let e=Bi(n),t=`${e}.claim-`,o=`${basename(e)}.claim-`,r=(()=>{try{return readdirSync$1(dirname$1(e)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(e),r):`${t}${Date.now()}-${process.pid}`;if(!r)try{renameSync(e,i);}catch{return null}let s=Ki(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function Ye(n){if(n.intents.shift(),n.intents.length===0){try{unlinkSync$1(n.path);}catch{}return}let e=`${n.path}.tmp-${process.pid}`;writeFileSync$1(e,n.intents.map(t=>JSON.stringify(t)).join(`
|
|
14
14
|
`)+`
|
|
15
|
-
`,{mode:384}),renameSync(e,n.path);}function ve(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
|
|
15
|
+
`,{mode:384}),renameSync(e,n.path);}function ve(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 Jn(n){let e=n.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!e)return null;let t=ve(e[1]);return t?{rawName:e[1],skillName:t}:null}function X(n,e){return e?`evt_tool_${createHash$1("sha256").update(`${n}\0${e}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var Z=1,ot="memory-snapshot-v1.json",oo=512*1024,ro=256*1024,io=2e3,ns=500,os=10,rs=240,is=300*1e3,ss=720*60*60*1e3,so=2147483647,as=100,Vn=250,cs=3e4,ls=10,be=new Map;function ao(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function D(n){return resolve(n)}function H(n){return createHash("sha256").update(D(n)).digest("hex").slice(0,16)}function rt(n,e={}){let t=H(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(D(n));return join(o,ot)}function Se(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function it(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function ds(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)&&it(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function us(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 st(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=D(e),i=H(r),s=o.generation===void 0?0:o.generation;return o.version!==Z||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>ro||!it(o.memoryIds,io)||!Array.isArray(o.conflicts)||o.conflicts.length>ns||!o.conflicts.every(ds)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+is||!Number.isInteger(s)||s<0||s>so||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!us(o.degradation)?null:{...o,generation:s}}function at(n,e,t,o,r=0){let i=D(n);return {version:Z,projectRoot:i,projectHash:H(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function N(n,e={}){let t=e.now??Date.now(),o=rt(n,e),r;try{r=openSync$1(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync$1(r);if(!i.isFile()||i.size<=0||i.size>oo)throw new Error("cache_size_invalid");let s=ao({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync$1(r,"utf8")),c=st(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>ss?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:at(n,a?"pending":"degraded",a?"cache_missing":Se(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync$1(r);}catch{}}}function Yn(n){if(!Number.isInteger(n)||n<0||n>=so)throw new Error("memory_snapshot_generation_exhausted");return n+1}function ps(n){let e=dirname$1(n);mkdirSync$1(e,{recursive:true,mode:448}),chmodSync(e,448);}function ms(n){ps(n);let e=`${n}.lock`,t={pid:process.pid,createdAt:Date.now(),token:randomUUID$1()},o=JSON.stringify(t),r;try{return r=openSync$1(e,"wx",384),writeFileSync$1(r,o),fsyncSync(r),{fd:r,path:e,contents:o}}catch(i){if(r!==void 0){try{closeSync$1(r);}catch{}try{unlinkSync$1(e);}catch{}}if(i.code==="EEXIST")return null;throw i}}function fs(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return Number.isInteger(e.pid)&&Number(e.pid)>0&&typeof e.createdAt=="number"&&Number.isFinite(e.createdAt)&&typeof e.token=="string"&&e.token.length>0}function hs(n){try{return process.kill(n,0),!1}catch(e){return e.code==="ESRCH"}}function gs(n){return !n.canonicalCachePath||!n.directoryIsSafe||!n.lockIsRegularFile||!n.metadataValid||!n.contentsUnchanged||!n.ownerDead&&!n.stale?false:n.currentUid!==void 0?n.directoryUid===n.currentUid&&n.lockUid===n.currentUid:true}function ys(n){return isAbsolute(n)&&resolve(n)===n&&basename(n)===ot&&/^[a-f0-9]{16}$/u.test(basename(dirname$1(n)))}function vs(n,e){let t=`${n}.lock`;try{let o=lstatSync$1(dirname$1(n)),r=lstatSync$1(t),i=readFileSync$1(t,"utf8"),s=null;try{let h=JSON.parse(i);fs(h)&&(s=h);}catch{}let a=s?.createdAt??r.mtimeMs,c=Date.now()-a>e,l=s?hs(s.pid):!1,d=readFileSync$1(t,"utf8")===i,u=typeof process.getuid=="function"?process.getuid():void 0,p=ao({...u!==void 0?{currentUid:u}:{},ownerUid:o.uid,mode:o.mode});return gs({canonicalCachePath:ys(n),directoryIsSafe:o.isDirectory()&&!o.isSymbolicLink()&&p.modeSafe,lockIsRegularFile:r.isFile()&&!r.isSymbolicLink(),metadataValid:s!==null,ownerDead:l,stale:c,contentsUnchanged:d,...u!==void 0?{currentUid:u}:{},directoryUid:o.uid,lockUid:r.uid})?(unlinkSync$1(t),!0):!1}catch{return false}}function bs(n){try{closeSync$1(n.fd);}catch{}try{readFileSync$1(n.path,"utf8")===n.contents&&unlinkSync$1(n.path);}catch{}}function ws(n){return new Promise(e=>setTimeout(e,n))}function Xe(n,e,t,o){let r=Number.isFinite(n)?Math.floor(n):e;return Math.min(o,Math.max(t,r))}async function Ss(n,e){let t=Xe(e.lockTimeoutMs,as,0,Vn),o=Xe(e.lockRetryMs,ls,1,Vn),r=Xe(e.lockStaleMs,cs,0,Number.MAX_SAFE_INTEGER),i=Date.now()+t;for(;;){let s=ms(n);if(s)return s;if(vs(n,r))continue;let a=i-Date.now();if(a<=0)throw new Error("memory_snapshot_cache_lock_timeout");await ws(Math.min(o,a));}}async function Xn(n,e,t){let o=await Ss(n,e);try{return await t()}finally{bs(o);}}function Qn(n,e,t,o){let r=o.now??Date.now(),i=D(n),s={version:Z,projectRoot:i,projectHash:H(i),markdown:e.markdown,memoryIds:e.memoryIds??[],conflicts:e.conflicts??[],generatedAt:r,generation:t,status:e.status??"ready",...e.degradation?{degradation:e.degradation}:{}};if(!st(s,n,r))throw new Error("memory_snapshot_payload_invalid");let a=JSON.stringify(s);if(Buffer.byteLength(a,"utf8")>oo)throw new Error("memory_snapshot_cache_too_large");let c=rt(n,o),l=dirname$1(c);mkdirSync$1(l,{recursive:true,mode:448}),chmodSync(l,448);let d=join(l,`.${ot}.${process.pid}.${randomUUID$1()}.tmp`),u;try{u=openSync$1(d,"wx",384),writeFileSync$1(u,a),fsyncSync(u),closeSync$1(u),u=void 0,chmodSync(d,384),renameSync(d,c),chmodSync(c,384);let p;try{p=openSync$1(l,"r");try{fsyncSync(p);}catch{}}finally{p!==void 0&&closeSync$1(p);}return s}finally{if(u!==void 0)try{closeSync$1(u);}catch{}rmSync$1(d,{force:true});}}function _s(n,e){let o=(be.get(n)??Promise.resolve()).catch(()=>{}).then(e),r=o.then(()=>{},()=>{});return be.set(n,r),o.finally(()=>{be.get(n)===r&&be.delete(n);})}function Qe(n,e,t,o,r){return n.valid?n.snapshot.generation>r?{...n,persisted:false}:{...n,snapshot:{...n.snapshot,status:"degraded",degradation:{reason:t,stale:n.stale||void 0}},persisted:false}:{snapshot:at(e,"degraded",t,o,r),source:"none",valid:false,stale:false,persisted:false}}async function ct(n){let e=rt(n.projectRoot,n.cacheOptions);return _s(e,async()=>{let t=N(n.projectRoot,n.cacheOptions),o=t.valid?t.snapshot.generation:0,r;try{r=await n.load();}catch(i){let s=Se(i,`refresh_failed:${n.reason}`);try{return await Xn(e,n.cacheOptions??{},()=>{let a=N(n.projectRoot,n.cacheOptions);if(a.valid)return Qe(a,n.projectRoot,s,n.cacheOptions?.now??Date.now(),o);let c=Yn(o),l=at(n.projectRoot,"degraded",s,n.cacheOptions?.now??Date.now(),c);return {snapshot:Qn(n.projectRoot,l,c,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(a){let c=N(n.projectRoot,n.cacheOptions);return Qe(c,n.projectRoot,Se(a,s),n.cacheOptions?.now??Date.now(),o)}}try{return await Xn(e,n.cacheOptions??{},()=>{let i=N(n.projectRoot,n.cacheOptions);if(i.valid&&i.snapshot.generation>o)return {...i,persisted:!1};let s=Yn(Math.max(o,i.valid?i.snapshot.generation:0));return {snapshot:Qn(n.projectRoot,r,s,n.cacheOptions??{}),source:"cache",valid:!0,stale:!1,persisted:!0}})}catch(i){let s=N(n.projectRoot,n.cacheOptions);return Qe(s,n.projectRoot,Se(i,`refresh_commit_failed:${n.reason}`),n.cacheOptions?.now??Date.now(),o)}})}async function Re(n){return ct({projectRoot:n.projectRoot,reason:n.reason,cacheOptions:n.cacheOptions,load:async()=>{if(n.injectConfig===false)return {status:"disabled",markdown:"",memoryIds:[],conflicts:[]};let e=typeof n.injectConfig=="object"?n.injectConfig:{},t=Number.isFinite(e.topN)?Math.max(0,Math.floor(e.topN)):10,o=Number.isFinite(e.budgetTokens)?Math.max(1,Math.floor(e.budgetTokens)):800,r=await n.memory.getAll({purpose:"session_bootstrap",budgetTokens:o,limit:t}),s=Number.isInteger(r.truncatedCount)&&r.truncatedCount>=0?r.truncatedCount:null,a=r.memories.length===0&&s!==0,c=s!==null&&s>0?"snapshot_results_truncated":"snapshot_truncation_unknown",l=(r.conflicts??[]).map(u=>({id:u.id,kind:u.kind,family:u.family,entity:u.entity,memoryIds:u.memoryIds,status:u.status,...u.summary?{summary:u.summary}:{}})),d=a?`## Project memory
|
|
16
16
|
DevFlow memory snapshot=degraded; reason=${c}. Memory result completeness is not authoritative; do not conclude that the project has no memories.`:r.memories.length===0&&l.length>0?`## Project memory
|
|
17
17
|
${l.length} explicit preference conflict(s) are withheld from automatic guidance; an explicit choice is required.`:r.memories.length===0?`## Project memory
|
|
18
18
|
\u672C\u9879\u76EE\u6682\u65E0\u8BB0\u5FC6`:`## Project memory (auto-injected, ${r.memories.length} items, ${r.tokenCount} tokens)
|
|
19
|
-
${r.memories.map(
|
|
20
|
-
`)}`;return {status:a?"degraded":"ready",markdown:
|
|
19
|
+
${r.memories.map(u=>`- **${u.title||u.type}**: ${u.content} (confidence ${u.confidence.toFixed(2)}, ${u.source})`).join(`
|
|
20
|
+
`)}`;return {status:a?"degraded":"ready",markdown:d,memoryIds:r.memories.map(u=>u.id),conflicts:l,...a?{degradation:{reason:c}}:{}}}})}function ks(n){if(!n)return true;try{return JSON.parse(readFileSync$1(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Rs(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=D(n);return {version:Z,projectRoot:i,projectHash:H(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=st(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=ro){let i=D(n);return {version:Z,projectRoot:i,projectHash:H(i),markdown:o.markdown,memoryIds:it(o.memoryIds,io)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function Ze(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,rs).join("")}function Is(n){if(n.length===0)return "";let e=n.slice(0,os),t=e.map(o=>{let r=Ze(o.family,"unknown"),i=Ze(o.entity,"unknown"),s=Ze(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
|
|
21
21
|
${t.join(`
|
|
22
|
-
`)}`}function
|
|
23
|
-
DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=
|
|
22
|
+
`)}`}function Es(n){let e=n.now??Date.now();if(ks(n.configPath)===false)return "";let t=Rs(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:N(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
|
|
23
|
+
DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=Is(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
|
|
24
24
|
`):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
|
|
25
|
-
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(ms({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var hs=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function gs(n){let e=n.trim();return e.length>0&&!hs.test(e)}function ys(n,e,t=Date.now()){let o=createHash("sha256").update(e.trim()).digest("hex"),r=createHash("sha256").update(`${n}\0${t}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:t}}function dt(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ee(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, preserve exact package names, flags, versions, paths, and identifiers; provide subject, predicate, value, polarity, and entities when known. 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 lt(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,o=n.status==="committed"?"; indexStatus=pending":"",r=n.status==="committed"&&n.source==="explicit_intent"?"; memoryOnlyCompleted=true; skipProjectContext=true; skipMemoryTool=true":"",i=n.status==="committed"&&n.source==="explicit_intent"?" This explicit-memory request is complete. Return the canonical receipt to the user. Do not call a memory tool, project-context tool, domain tool, or native memory write for this request.":"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${o}${r}.`+i}function ut(n){if(!gs(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),o=createHash("sha256").update(t).digest("hex"),r=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(l=>l.promptHash===o&&Date.now()-l.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:ys(n.sessionId,t),s=r??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:lt(s),skipSkillRouting:s.source==="explicit_intent"};let a=ye(t)??void 0,c=a?"commit_explicit":"capture_prompt";return e.enqueueWork({idempotencyKey:`memory-turn:${c}:${s.turnId}`,kind:a?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:c,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:a,createdAt:s.createdAt}}),{turn:s,explicitContent:a,additionalContext:a?`DevFlow explicit memory is durably queued for ${s.turnId}, but no canonical receipt exists yet. Do not claim that it was remembered.`:Ee(s),skipSkillRouting:!!a}}finally{e.close();}}async function pt(n){let{payload:e,memory:t,projectRoot:o}=n,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:lt(i),skipSkillRouting:i.source==="explicit_intent"};if(await t.recordUserMessage(e.prompt,e.sessionId,e.prompt.slice(0,200)),await t.recordEvent({id:e.eventId,sessionId:e.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:e.prompt,turnId:e.turnId},createdAt:e.createdAt}),e.operation==="capture_prompt"||!e.explicitContent)return {turn:i,additionalContext:Ee(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=dt(i.turnId,"committed",[s.id]),c=r.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(l){console.error("[devflow] Explicit memory enrichment deferred:",l.message),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${s.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Re({projectRoot:o,memory:t,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(l){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",l.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:lt(c),skipSkillRouting:!0}}finally{r.close();}}var Ss=new Set(["Write","Edit","NotebookEdit"]),ro="Claude native memory writes are disabled for this project. Use DevFlow explicit memory or mcp__devflow__memory_commit_turn so a canonical receipt is created.";function lo(n){if(!Ss.has(n.toolName))return null;let e=_s(n.toolInput);if(!e)return null;let t=ws(e,n.projectRoot),o=resolve(n.projectRoot,".claude");if(io(t,o)&&basename(t).toLocaleUpperCase("en-US")==="MEMORY.MD")return ro;let r=resolve(n.home??homedir(),".claude","projects");return io(t,r)&&relative(r,t).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?ro:null}function _s(n){for(let e of ["file_path","notebook_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}return null}function ws(n,e){return resolve(isAbsolute(n)?n:resolve(e,n))}function io(n,e){let t=relative(e,n);return t===""||!t.startsWith(`..${sep}`)&&t!==".."&&!isAbsolute(t)}var Ts=1024*1024;function mo(n){let e=join(getProjectStateDir(n),"session-start-pending");mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Ts)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function fo(n){unlinkSync$1(n.path);}function ho(n){let e=n.path.replace(/\.claim-\d+$/u,"");try{renameSync(n.path,e);}catch{}}function yo(n,e){let t=_o(n);mkdirSync$1(t,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(t,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function vo(n){let e=_o(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function bo(n){unlinkSync$1(n.path);}function So(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function _o(n){return join(E(n),"memory-turn-pending")}var L=class extends Error{constructor(e,t){super(t),this.name="PermanentWorkError",this.category=e;}},Fs=1e3,$s=3e4,Ns=1,Ls=5*6e4,Te=class{constructor(e){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=e.projectRoot,this.handlers=e.handlers,this.pollIntervalMs=yt(e.pollIntervalMs,Fs),this.leaseMs=yt(e.leaseMs,$s),this.batchSize=yt(e.batchSize,Ns),this.owner=e.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=e.now??Date.now,this.random=e.random??Math.random,this.openDatabase=e.openDatabase??(()=>openGlobalDevFlowDatabase());}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}schedule(e){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(t=>console.error("[devflow-work] Drain failed:",wo(t))).finally(()=>this.schedule(this.pollIntervalMs));},e),this.timer.unref());}async performDrain(){let e=Object.keys(this.handlers);if(e.length===0)return 0;let t=this.openDatabase();try{let o=this.now();t.recoverExpiredWork(this.projectRoot,o);let r=t.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:e,limit:this.batchSize,leaseMs:this.leaseMs,now:o});for(let i of r)await this.processItem(t,i);return r.length}finally{t.close();}}async processItem(e,t){let o=this.handlers[t.kind];if(!o){e.deadLetterWork(t.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${t.kind}`});return}try{if(await o({item:t}),!e.completeWork(t.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${t.id}`)}catch(r){let i=Hs(r);if(r instanceof L){e.deadLetterWork(t.id,this.owner,i);return}let s=this.now()+Math.max(Us(t.attempts,this.random()),i.retryAfterMs??0);if(i.retryWithoutAttempt){e.deferWork(t.id,this.owner,i,s);return}e.retryWork(t.id,this.owner,i,s);}}};function yt(n,e){return Number.isSafeInteger(n)&&n>0?n:e}function Hs(n){if(n instanceof L)return {category:n.category,message:n.message};let e=n&&typeof n=="object"?n:null;return {category:typeof e?.category=="string"?e.category:"runtime_error",message:wo(n),retryAfterMs:typeof e?.retryAfterMs=="number"&&Number.isFinite(e.retryAfterMs)?Math.max(0,e.retryAfterMs):void 0,retryWithoutAttempt:e?.retryWithoutAttempt===true}}function Us(n,e){let t=Math.min(Ls,500*2**Math.max(0,n-1)),o=Math.floor(t*.2*Math.max(0,Math.min(1,e)));return t+o}function wo(n){return n instanceof Error?n.message:String(n)}var Bs=250;function Io(n,e=process.env){let t=Ro(join(homedir(),".devflow","config.json")),o=Ro(join(n,".devflow","config.json")),r=vt(e.DEVFLOW_HOOK_PROFILE)??vt(o.profile)??vt(t.profile)??"standard",i=Number(e.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??t.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):Bs,a=new Set([...bt(t.disabledHandlers),...bt(o.disabledHandlers),...bt(e.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(Ys).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Me(n,e,t,o){let r,i=new Promise(s=>{r=setTimeout(()=>{console.error(`[devflow-hook] ${n} exceeded ${e}ms acknowledgement budget`),s(o());},e),r.unref();});try{return await Promise.race([Promise.resolve().then(t),i])}finally{r&&clearTimeout(r);}}async function Eo(n,e=process.env){let t=e.DEVFLOW_HOST_ADAPTER??(e.CLAUDE_PROJECT_DIR||e.CLAUDE_PLUGIN_ROOT||e.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:n,env:e,explicitHost:t});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:n,env:e,explicitHost:t});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function xo(n,e,t){let o=Ks(n,e.profile);if(!t.profiles.has(e.profile))return {enabled:false,policy:"fail_open",reason:`hook_profile_${e.profile}_unsupported_by_${t.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(e.disabledHandlers.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(e.profile==="minimal"&&!Gs.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let r=Vs[n];if(!r)return {enabled:true,policy:o};let i=t.capabilities.get(r);return !i||i.status!=="supported"?{enabled:false,policy:"fail_open",reason:i?.reason??`${r}_unsupported_by_${t.hostId}`,fallback:i?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var Gs=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),Vs={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function Ks(n,e){return n==="user-prompt-submit"||n==="stop"||n==="session-end"?"enqueue_and_open":n==="pre-tool-use"&&e==="strict"?"fail_closed":"fail_open"}function Ro(n){if(!existsSync(n))return {};try{let t=JSON.parse(readFileSync$1(n,"utf8")).hooks;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return {}}}function vt(n){return n==="minimal"||n==="standard"||n==="strict"?n:void 0}function bt(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):[]}function Ys(n){let e=n.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[e.replace(/-/g,"")]??e)||void 0}function To(n){let e=Dn({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{ea(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(Ee(o)),o&&!r&&Qs(t,o.turnId)&&Zs(fe(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
|
|
25
|
+
`)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(Es({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}var Ms=/^(?:ok(?:ay)?|yes|no|thanks?|thank you|continue|好的?|可以|行|是|否|谢谢|继续|收到|明白了?)[.!。!\s]*$/iu;function Ts(n){let e=n.trim();return e.length>0&&!Ms.test(e)}function Cs(n,e,t=Date.now()){let o=createHash("sha256").update(e.trim()).digest("hex"),r=createHash("sha256").update(`${n}\0${t}\0${o}`).digest("hex").slice(0,24);return {turnId:`turn:${r}`,eventId:`memory-turn:${r}`,promptHash:o,createdAt:t}}function dt(n,e,t=[]){return `memory-receipt:${createHash("sha256").update(`${n}\0${e}\0${[...t].sort().join("\0")}`).digest("hex").slice(0,24)}`}function Ee(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, preserve exact package names, flags, versions, paths, and identifiers; provide subject, predicate, value, polarity, and entities when known. 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 lt(n){let e=n.memoryIds.length>0?n.memoryIds.join(","):"none",t=n.status==="committed"?"accepted":n.status,o=n.status==="committed"?"; indexStatus=pending":"",r=n.status==="committed"&&n.source==="explicit_intent"?"; memoryOnlyCompleted=true; skipProjectContext=true; skipMemoryTool=true":"",i=n.status==="committed"&&n.source==="explicit_intent"?" This explicit-memory request is complete. Return the canonical receipt to the user. Do not call a memory tool, project-context tool, domain tool, or native memory write for this request.":"";return `DevFlow canonical memory receipt: status=${t}; receiptId=${n.receiptId??"missing"}; turnId=${n.turnId}; memoryIds=${e}; source=${n.source??"unknown"}${o}${r}.`+i}function ut(n){if(!Ts(n.prompt))return null;let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let t=n.prompt.trim().slice(0,4e3),o=createHash("sha256").update(t).digest("hex"),r=e.listMemoryTurns(n.projectRoot,n.sessionId,5).find(l=>l.promptHash===o&&Date.now()-l.createdAt<1e4),i=r?{turnId:r.turnId,eventId:r.eventId,promptHash:r.promptHash,createdAt:r.createdAt}:Cs(n.sessionId,t),s=r??e.beginMemoryTurn({...i,projectRoot:n.projectRoot,sessionId:n.sessionId});if(s.status!=="pending")return {turn:s,additionalContext:lt(s),skipSkillRouting:s.source==="explicit_intent"};let a=ye(t)??void 0,c=a?"commit_explicit":"capture_prompt";return e.enqueueWork({idempotencyKey:`memory-turn:${c}:${s.turnId}`,kind:a?"memory.explicit_commit":"memory.turn_capture",projectRoot:n.projectRoot,sessionId:n.sessionId,turnId:s.turnId,payload:{operation:c,turnId:s.turnId,eventId:s.eventId,sessionId:n.sessionId,prompt:t,explicitContent:a,createdAt:s.createdAt}}),{turn:s,explicitContent:a,additionalContext:a?`DevFlow explicit memory is durably queued for ${s.turnId}, but no canonical receipt exists yet. Do not claim that it was remembered.`:Ee(s),skipSkillRouting:!!a}}finally{e.close();}}async function pt(n){let{payload:e,memory:t,projectRoot:o}=n,r=openGlobalDevFlowDatabase();try{let i=r.getMemoryTurn(e.turnId);if(!i)throw new Error(`Memory turn ${e.turnId} does not exist`);if(i.status!=="pending")return {turn:i,additionalContext:lt(i),skipSkillRouting:i.source==="explicit_intent"};if(await t.recordUserMessage(e.prompt,e.sessionId,e.prompt.slice(0,200)),await t.recordEvent({id:e.eventId,sessionId:e.sessionId,tool:"UserPromptSubmit",kind:"user_message",payload:{prompt:e.prompt,turnId:e.turnId},createdAt:e.createdAt}),e.operation==="capture_prompt"||!e.explicitContent)return {turn:i,additionalContext:Ee(i),skipSkillRouting:!1};let s=await t.saveExplicitMemoryIntent(e.explicitContent,e.sessionId,e.eventId),a=dt(i.turnId,"committed",[s.id]),c=r.commitMemoryTurn({turnId:i.turnId,receiptId:a,memoryIds:[s.id],source:"explicit_intent",reason:"explicit_user_request"});try{await t.enrichExplicitMemoryObservation(s.id);}catch(l){console.error("[devflow] Explicit memory enrichment deferred:",l.message),r.enqueueWork({idempotencyKey:`explicit-enrichment:${o}:${s.id}`,kind:"memory.explicit_enrichment",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});}r.enqueueWork({idempotencyKey:`vector:${o}:${s.id}`,kind:"memory.vector_backfill",projectRoot:o,sessionId:e.sessionId,turnId:c.turnId,payload:{observationId:s.id},maxAttempts:20});try{await Re({projectRoot:o,memory:t,injectConfig:loadConfig(o).sessionStart?.injectMemories,reason:"explicit_memory_commit"});}catch(l){console.error("[devflow] Memory snapshot refresh failed after canonical commit:",l.message);}return {turn:c,explicitContent:e.explicitContent,additionalContext:lt(c),skipSkillRouting:!0}}finally{r.close();}}var Os=new Set(["Write","Edit","NotebookEdit"]),lo="Claude native memory writes are disabled for this project. Use DevFlow explicit memory or mcp__devflow__memory_commit_turn so a canonical receipt is created.";function ho(n){if(!Os.has(n.toolName))return null;let e=Ps(n.toolInput);if(!e)return null;let t=js(e,n.projectRoot),o=resolve(n.projectRoot,".claude");if(uo(t,o)&&basename(t).toLocaleUpperCase("en-US")==="MEMORY.MD")return lo;let r=resolve(n.home??homedir(),".claude","projects");return uo(t,r)&&relative(r,t).split(sep).some(s=>s.toLocaleLowerCase("en-US")==="memory")?lo:null}function Ps(n){for(let e of ["file_path","notebook_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}return null}function js(n,e){return resolve(isAbsolute(n)?n:resolve(e,n))}function uo(n,e){let t=relative(e,n);return t===""||!t.startsWith(`..${sep}`)&&t!==".."&&!isAbsolute(t)}var Us=1024*1024;function vo(n){let e=join(getProjectStateDir(n),"session-start-pending");mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=readFileSync$1(i,"utf8");if(Buffer.byteLength(s,"utf8")>Us)throw unlinkSync$1(i),new Error("session_start_spool_input_too_large");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),input:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function bo(n){unlinkSync$1(n.path);}function wo(n){let e=n.path.replace(/\.claim-\d+$/u,"");try{renameSync(n.path,e);}catch{}}function _o(n,e){let t=Eo(n);mkdirSync$1(t,{recursive:true,mode:448});let o=`memory-turn-spool-${Date.now()}-${process.pid}-${randomUUID$1()}`,r=join(t,`${o}.json`),i=`${r}.tmp`;return writeFileSync$1(i,JSON.stringify({...e,prompt:e.prompt.trim().slice(0,4e3)}),{mode:384}),renameSync(i,r),o}function ko(n){let e=Eo(n);mkdirSync$1(e,{recursive:true,mode:448});let t=readdirSync$1(e).filter(s=>s.endsWith(".json")||/\.json\.claim-\d+$/u.test(s)).sort()[0];if(!t)return null;let o=join(e,t),r=/\.json\.claim-\d+$/u.test(t),i=r?o:`${o}.claim-${process.pid}`;if(!r)try{renameSync(o,i);}catch{return null}try{let s=JSON.parse(readFileSync$1(i,"utf8"));if(typeof s.sessionId!="string"||typeof s.prompt!="string"||typeof s.createdAt!="number")throw unlinkSync$1(i),new Error("memory_turn_spool_payload_invalid");return {receiptId:basename(t).replace(/\.json(?:\.claim-\d+)?$/u,""),payload:s,path:i}}catch(s){try{unlinkSync$1(i);}catch{}throw s}}function Ro(n){unlinkSync$1(n.path);}function Io(n){try{renameSync(n.path,n.path.replace(/\.claim-\d+$/u,""));}catch{}}function Eo(n){return join(E(n),"memory-turn-pending")}var T=class extends Error{constructor(e,t){super(t),this.name="PermanentWorkError",this.category=e;}},Vs=1e3,Ys=3e4,Xs=1,Qs=5*6e4,Me=class{constructor(e){this.timer=null;this.draining=null;this.stopped=true;this.projectRoot=e.projectRoot,this.handlers=e.handlers,this.pollIntervalMs=yt(e.pollIntervalMs,Vs),this.leaseMs=yt(e.leaseMs,Ys),this.batchSize=yt(e.batchSize,Xs),this.owner=e.owner??`hook-daemon:${process.pid}:${randomUUID$1()}`,this.now=e.now??Date.now,this.random=e.random??Math.random,this.openDatabase=e.openDatabase??(()=>openGlobalDevFlowDatabase()),this.afterComplete=e.afterComplete;}start(){this.stopped&&(this.stopped=false,this.schedule(0));}stop(){this.stopped=true,this.timer&&clearTimeout(this.timer),this.timer=null;}drainOnce(){return this.draining?this.draining:(this.draining=this.performDrain().finally(()=>{this.draining=null;}),this.draining)}schedule(e){this.stopped||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>{this.timer=null,this.drainOnce().catch(t=>console.error("[devflow-work] Drain failed:",vt(t))).finally(()=>this.schedule(this.pollIntervalMs));},e),this.timer.unref());}async performDrain(){let e=Object.keys(this.handlers);if(e.length===0)return 0;let t=this.openDatabase();try{let o=this.now();t.recoverExpiredWork(this.projectRoot,o);let r=t.leaseWork({projectRoot:this.projectRoot,owner:this.owner,kinds:e,limit:this.batchSize,leaseMs:this.leaseMs,now:o});for(let i of r)await this.processItem(t,i);return r.length}finally{t.close();}}async processItem(e,t){let o=this.handlers[t.kind];if(!o){e.deadLetterWork(t.id,this.owner,{category:"unsupported_work_kind",message:`No work handler is registered for ${t.kind}`});return}try{if(await o({item:t}),!e.completeWork(t.id,this.owner,this.now()))throw new Error(`Work lease was lost before completion: ${t.id}`);try{await this.afterComplete?.({item:t,database:e});}catch(r){console.error("[devflow-work] Completion follow-up failed:",vt(r));}}catch(r){let i=Zs(r);if(r instanceof T){e.deadLetterWork(t.id,this.owner,i);return}let s=this.now()+Math.max(ea(t.attempts,this.random()),i.retryAfterMs??0);if(i.retryWithoutAttempt){e.deferWork(t.id,this.owner,i,s);return}e.retryWork(t.id,this.owner,i,s);}}};function yt(n,e){return Number.isSafeInteger(n)&&n>0?n:e}function Zs(n){if(n instanceof T)return {category:n.category,message:n.message};let e=n&&typeof n=="object"?n:null;return {category:typeof e?.category=="string"?e.category:"runtime_error",message:vt(n),retryAfterMs:typeof e?.retryAfterMs=="number"&&Number.isFinite(e.retryAfterMs)?Math.max(0,e.retryAfterMs):void 0,retryWithoutAttempt:e?.retryWithoutAttempt===true}}function ea(n,e){let t=Math.min(Qs,500*2**Math.max(0,n-1)),o=Math.floor(t*.2*Math.max(0,Math.min(1,e)));return t+o}function vt(n){return n instanceof Error?n.message:String(n)}var ia=250;function To(n,e=process.env){let t=Mo(join(homedir(),".devflow","config.json")),o=Mo(join(n,".devflow","config.json")),r=bt(e.DEVFLOW_HOOK_PROFILE)??bt(o.profile)??bt(t.profile)??"standard",i=Number(e.DEVFLOW_HOOK_ACK_BUDGET_MS??o.acknowledgementBudgetMs??t.acknowledgementBudgetMs),s=Number.isSafeInteger(i)&&i>0?Math.min(i,5e3):ia,a=new Set([...wt(t.disabledHandlers),...wt(o.disabledHandlers),...wt(e.DEVFLOW_DISABLED_HOOK_HANDLERS?.split(","))].map(la).filter(c=>!!c));return {profile:r,acknowledgementBudgetMs:s,disabledHandlers:a}}async function Te(n,e,t,o){let r,i=new Promise(s=>{r=setTimeout(()=>{console.error(`[devflow-hook] ${n} exceeded ${e}ms acknowledgement budget`),s(o());},e),r.unref();});try{return await Promise.race([Promise.resolve().then(t),i])}finally{r&&clearTimeout(r);}}async function Co(n,e=process.env){let t=e.DEVFLOW_HOST_ADAPTER??(e.CLAUDE_PROJECT_DIR||e.CLAUDE_PLUGIN_ROOT||e.CLAUDE_CODE_ENTRYPOINT?"claude-code":void 0),o=await selectHostAdapter({projectRoot:n,env:e,explicitHost:t});if(o.status==="failed")throw new Error(`host_adapter_selection_failed:${o.code}:${o.reason}`);let r=await o.adapter.capabilities({projectRoot:n,env:e,explicitHost:t});return {hostId:o.adapter.id,capabilities:new Map(r.map(i=>[i.capability,i])),profiles:new Set(o.adapter.hooks?.profileSupport??[])}}function Do(n,e,t){let o=ca(n,e.profile);if(!t.profiles.has(e.profile))return {enabled:false,policy:"fail_open",reason:`hook_profile_${e.profile}_unsupported_by_${t.hostId}`,fallback:"host_event_continues_without_devflow_handler"};if(e.disabledHandlers.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_disabled",fallback:"host_event_continues_without_devflow_handler"};if(e.profile==="minimal"&&!sa.has(n))return {enabled:false,policy:"fail_open",reason:"hook_handler_not_in_minimal_profile",fallback:"critical_receipts_only"};let r=aa[n];if(!r)return {enabled:true,policy:o};let i=t.capabilities.get(r);return !i||i.status!=="supported"?{enabled:false,policy:"fail_open",reason:i?.reason??`${r}_unsupported_by_${t.hostId}`,fallback:i?.fallback??"host_event_continues_without_native_hook_processing"}:{enabled:true,policy:o}}var sa=new Set(["session-start","user-prompt-submit","stop","session-end","memory-snapshot"]),aa={"session-start":"hooks.session_start","user-prompt-submit":"hooks.prompt_submit","pre-tool-use":"hooks.pre_tool_use","post-tool-use":"hooks.post_tool_use","post-tool-use-failure":"hooks.post_tool_use",stop:"hooks.stop","session-end":"hooks.session_end"};function ca(n,e){return n==="user-prompt-submit"||n==="stop"||n==="session-end"?"enqueue_and_open":n==="pre-tool-use"&&e==="strict"?"fail_closed":"fail_open"}function Mo(n){if(!existsSync(n))return {};try{let t=JSON.parse(readFileSync$1(n,"utf8")).hooks;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return {}}}function bt(n){return n==="minimal"||n==="standard"||n==="strict"?n:void 0}function wt(n){return Array.isArray(n)?n.filter(e=>typeof e=="string"):[]}function la(n){let e=n.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/_/g,"-").toLowerCase();return ({sessionstart:"session-start",userpromptsubmit:"user-prompt-submit",pretooluse:"pre-tool-use",posttooluse:"post-tool-use",posttoolusefailure:"post-tool-use-failure",sessionend:"session-end",precompact:"pre-compact",memorysnapshot:"memory-snapshot"}[e.replace(/-/g,"")]??e)||void 0}function Ao(n){let e=jn({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{ma(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(Ee(o)),o&&!r&&ua(t,o.turnId)&&pa(fe(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
|
|
26
26
|
|
|
27
|
-
`)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function
|
|
28
|
-
`);if(t=d.pop()??"",Buffer.byteLength(t,"utf8")>Do){a();return}if(d.length===0)return;let p=0;for(let g of d){let h=Buffer.byteLength(g,"utf8");if(h>Do){a();return}p+=h+1;}if(i+p>Da){a();return}i+=p,s=s.then(async()=>{for(let g of d){if(r)return;if(!o){let h;try{h=JSON.parse(g);}catch{await l({error:"handshake_invalid"});return}if(h?.type!=="hello"||typeof h.rootPath!="string"){await l({error:"handshake_invalid"});return}if(h.rootPath!==this.projectRoot){await l({error:"handshake_root_mismatch",expected:this.projectRoot});return}o=true,clearTimeout(c),this.resetIdleTimer();continue}if(g.trim())try{let h=JSON.parse(g),v=await this.handleRequest(h);v!==null&&!r&&await this.writeFrame(e,v);}catch(h){r||await this.writeFrame(e,{error:h.message});}}}).catch(()=>{a();}).finally(()=>{i-=p;});}),e.on("close",()=>clearTimeout(c)),e.on("error",()=>{});}writeFrame(e,t){return new Promise((o,r)=>{if(e.destroyed||!e.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{e.destroy(),u(new Error("Timed out writing daemon response"));},Ma),l=()=>{clearTimeout(c),e.off("close",d),e.off("error",p),e.off("drain",g);},u=v=>{a||!v&&(!i||!s)||(a=true,l(),v?r(v):o());},d=()=>u(new Error("Socket closed during write")),p=v=>u(v),g=()=>{s=true,u();};e.once("close",d),e.once("error",p),e.write(`${JSON.stringify(t)}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
`)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function ua(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function pa(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function ma(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);!s||s.state!=="open"||t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",reason:r.reason,resolvedAt:r.completedAt});}}}function Oo(n){let e;try{e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let t=e.getActiveContextReceipt(n.projectRoot,n.sessionId,n.executionId);if(!t)return null;let o=n.toolName==="Read"?ya(n.toolInput):void 0,r=o?t.selectedFiles?.find(l=>va(n.projectRoot,l,o)):void 0,i=ba(n.toolName),s=r?"code":t.canonicalNextAction===i?"action":null,a=r??(s==="action"?i:void 0);if(!s||!a)return null;let c=[t.contextHash,t.requestId??"",s,a,n.toolUseId??`${n.sessionId}:${n.executionId??t.executionId}`].join("\0");return e.recordContextSelectionEvent({id:`ctxsel:${createHash("sha256").update(c).digest("hex").slice(0,32)}`,projectRoot:n.projectRoot,sessionId:n.sessionId,executionId:t.executionId,requestId:t.requestId,selectionType:s,candidateId:a,toolName:n.toolName,toolUseId:n.toolUseId,selectedAt:Date.now()}),s}catch{return null}finally{try{e?.close();}catch{}}}function ya(n){for(let e of ["file_path","path"]){let t=n[e];if(typeof t=="string"&&t.trim())return t.trim()}}function va(n,e,t){let o=resolve(n,e),r=isAbsolute(t)?resolve(t):resolve(n,t);return o===r}function ba(n){return n.startsWith("mcp__")?n.split("__").at(-1)??n:n}var wa=[/\b(?:rm\s+-rf|sudo|chmod|chown|force\s+push|reset\s+--hard|publish|release|deploy)\b/iu,/\b(?:secret|credential|token|password|security|authentication|authorization)\b/iu,/(?:删除|强制推送|发布|部署|凭据|密钥|安全|权限)/u],Sa=[/\b(?:migration|upgrade|dependency|dependencies|generated files?|write all|rewrite)\b/iu,/(?:迁移|升级|依赖|生成文件|批量写入)/u];function _t(n){let e=`${n.instruction}
|
|
28
|
+
${JSON.stringify(n.trigger)}`,t=[];wa.some(r=>r.test(e))&&t.push("high_risk_operation"),Sa.some(r=>r.test(e))&&t.push("broad_or_migrating_change"),n.kind==="correction"&&t.push("user_correction_requires_observation");let o=t.includes("high_risk_operation")?"high":t.includes("broad_or_migrating_change")||n.scope==="global"?"medium":"low";return {risk:o,manualOnly:o==="high"||t.includes("broad_or_migrating_change"),reasons:t}}var _a=new Set(["project_convention","user_preference","decision_made","config_discovery"]);function Rt(n){let e=n.payload.executionId?n.database.getSkillExecution(n.payload.executionId):n.database.getLatestSkillExecutionForSession(n.payload.sessionId),t=n.database.listHostActionsForSession(n.payload.projectRoot,n.payload.sessionId,n.payload.executionId),o=t.find(d=>d.state==="verified"),r=t.find(d=>["failed","cancelled","degraded"].includes(d.state)),i=r?"negative":o?"positive":"unknown",s=new Set,a=[],c=0,l=0;for(let d of n.evidence){if(!ka(d)){l+=1;continue}let u=$o(d),p=Ra(d,e?.skillName),h=No(d),m=xa(n.payload.projectRoot,u,d.facetKey??d.semanticKey??d.id,p),y=n.database.getLearningCandidate(m),b=_t({scope:"project",kind:u,instruction:h,trigger:p});n.database.upsertLearningCandidate({id:m,projectRoot:n.payload.projectRoot,scope:"project",kind:u,trigger:p,instruction:h,confidence:Ia(d),manualOnly:b.manualOnly,risk:b.risk});y&&y.instruction!==h&&n.database.addLearningCandidateEvidence({id:Po(m,n.payload.sessionId,d.id,"contradicting"),candidateId:m,projectRoot:n.payload.projectRoot,sessionId:n.payload.sessionId,executionId:n.payload.executionId,memoryObservationId:d.id,sourceType:"correction",polarity:"contradicting",outcome:i,evidenceHash:jo(m,n.payload,d,"contradicting"),receipt:n.payload.closureReceipt,payload:{previousInstruction:y.instruction,replacementInstruction:h,projectRevision:n.payload.projectRevision},createdAt:d.createdAt});let S=n.database.addLearningCandidateEvidence({id:Po(m,n.payload.sessionId,d.id,"supporting"),candidateId:m,projectRoot:n.payload.projectRoot,sessionId:n.payload.sessionId,executionId:n.payload.executionId,memoryObservationId:d.id,outcomeId:o?.id??r?.id,sourceType:Ea(d),polarity:"supporting",outcome:i,evidenceHash:jo(m,n.payload,d,"supporting"),receipt:n.payload.closureReceipt,payload:{semanticKey:d.semanticKey,facetKey:d.facetKey,evidenceStatus:d.evidenceStatus,source:d.source,projectRevision:n.payload.projectRevision,executionStatus:e?.status,policyReasons:b.reasons},createdAt:d.createdAt});c+=1,s.add(m),n.rolloutMode!=="off"&&S.state==="candidate"&&S.supportingSessions>=3&&S.successfulOutcomes>=2&&n.database.transitionLearningCandidate(m,{target:"shadow",reason:"evidence_threshold_satisfied"}).state==="shadow"&&a.push(m);}return {considered:n.evidence.length,accepted:c,excluded:l,candidateIds:[...s],promotedToShadow:a}}function ka(n){return !(!_a.has(n.type)||n.source!=="explicit_intent"&&n.source!=="manual"&&n.evidenceStatus!=="verified"||!n.narrative.trim()&&!n.title.trim())}function $o(n){return n.type==="decision_made"?"workflow":n.type==="user_preference"&&(n.semanticValue.startsWith("--")||n.tools.length>0)?"tool_preference":"convention"}function Ra(n,e){return {...e?{skills:[e]}:{},...n.entities.length>0?{entities:[...new Set(n.entities)].slice(0,8)}:{},...n.files.length>0?{files:[...new Set(n.files)].slice(0,8)}:{},...n.tools.length>0?{commands:[...new Set(n.tools)].slice(0,8)}:{},semantic:{subject:n.semanticSubject,predicate:n.semanticPredicate,value:n.semanticValue,polarity:n.semanticPolarity}}}function No(n){return (n.narrative.trim()||n.title.trim()).replace(/\s+/gu," ").slice(0,1200)}function Ia(n){let e=n.source==="explicit_intent"?.08:0;return Math.max(0,Math.min(1,n.confidence+e))}function Ea(n){return n.semanticPolarity==="negative"?"correction":$o(n)==="tool_preference"?"tool_preference":n.source==="explicit_intent"?"memory":"convention"}function xa(n,e,t,o){let r={...o,semantic:void 0};return `learning:${createHash("sha256").update(`${n}\0project\0${e}\0${t}\0${stableLearningJson(r)}`).digest("hex").slice(0,24)}`}function Po(n,e,t,o){return `learning-evidence:${createHash("sha256").update(`${n}\0${e}\0${t}\0${o}`).digest("hex").slice(0,24)}`}function jo(n,e,t,o){return createHash("sha256").update(stableLearningJson({candidateId:n,sessionId:e.sessionId,executionId:e.executionId,closureReceipt:e.closureReceipt,projectRevision:e.projectRevision,observationId:t.id,instruction:No(t),polarity:o})).digest("hex")}var qa=600*1e3,Ja=2e3,Ga=250,Ba=2e3,Ka=1e3,Ho=1024*1024,Va=2*1024*1024,Ya=6e4,Xa=100,Qa={Agent:"get_project_context",Bash:"get_project_context",Glob:"get_project_context",Grep:"get_project_context",WebSearch:"get_knowledge",WebFetch:"get_knowledge"};function Za(n){switch(n){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}function Et(n){return typeof n=="string"&&n.trim().length>0}function ec(n,e,t=process.env,o){if(!n.startsWith("mcp__devflow__"))return e;let r=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{};if(Et(r.projectRoot))return r;let i=Et(t.CLAUDE_PROJECT_DIR)?t.CLAUDE_PROJECT_DIR:o;return Et(i)&&(r.projectRoot=i),r}var xt=class{constructor(e,t){this.socketIdentity=null;this.pidIdentity=null;this.server=null;this.activeSessionIds=new Set;this.eventMap=[];this.idleTimer=null;this.telemetryFlushTimer=null;this.successfulTelemetryOperations=0;this.shutdownPromise=null;this.explicitMemoryGate=null;this.memoryWarmup=null;this.explicitIntentFlush=null;this.hostRuntime=null;this.memoryTurnSpoolTimer=null;this.sessionFinalizeSpoolTimer=null;this.projectRoot=e,this.socketPath=getDaemonSocketPath(e),this.pidPath=getDaemonPidPath(e),this.telemetry=new P,this.runtimeStore=new M(this.projectRoot),this.serverManager=new se(e),this.hookRuntime=To(e),this.initialSessionInput=t,this.workRuntime=new Me({projectRoot:e,handlers:{"memory.explicit_commit":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.turn_capture":async({item:o})=>{await this.persistMemoryTurnItem(o.payload);},"memory.explicit_enrichment":async({item:o})=>{let r=o.payload;if(typeof r?.observationId!="string"||!r.observationId)throw new T("invalid_payload","Explicit enrichment requires observationId");await(await this.getMemoryGate()).enrichExplicitMemoryObservation(r.observationId);},"session.bootstrap":async({item:o})=>{await this.bootstrapSessionWork(o.payload);},"memory.vector_backfill":async()=>{await(await this.getMemoryGate()).backfillObservationVectors({batchSize:32});},"memory.turn_distill":async({item:o})=>{await B({projectRoot:this.projectRoot,sessionId:o.sessionId,trigger:"session_end",memory:await this.getMemoryGate()}),await this.refreshMemorySnapshot("memory_turn_distill");},"context.prefetch":async({item:o})=>{let r=o.payload;if(typeof r.prompt!="string"||typeof r.sessionId!="string"||typeof r.executionId!="string"||typeof r.profileFingerprint!="string"||typeof r.rolloutMode!="string")throw new T("invalid_payload","Context prefetch identity is incomplete");let{createEngines:i,writeContextPrefetchCache:s}=await import('@devflow-tools/context-engine'),a=await i(this.projectRoot);try{let c=await a.context.buildTaskContext(r.prompt,{mode:"fast",sessionId:r.sessionId,executionId:r.executionId,activeSkill:r.skillName});if(!s({projectRoot:this.projectRoot,query:r.prompt,sessionId:r.sessionId,executionId:r.executionId,profileFingerprint:r.profileFingerprint,rolloutMode:r.rolloutMode,retrievalVersion:r.retrievalVersion},c))throw new Error("Context prefetch envelope was not receipt-valid")}finally{for(let c of Object.values(a))try{c.close?.();}catch{}}},"learning.analyze_session":async({item:o})=>{let r=o.payload;if(typeof r.projectRoot!="string"||typeof r.sessionId!="string"||typeof r.closureReceipt!="string"||typeof r.projectRevision!="string"||typeof r.createdAt!="number")throw new T("invalid_payload","Learning analysis identity is incomplete");let i=openGlobalDevFlowDatabase();try{let s=await(await this.getMemoryGate()).listLearningEvidence(r.sessionId),a=Rt({payload:r,evidence:s,database:i,rolloutMode:resolveCapabilityRollout(this.projectRoot).config.learningOverlays});i.insertEvent({kind:"learning_analysis",timestamp:Date.now(),success:!0,metadata:{...r,...a}});}finally{i.close();}},"session.finalize":async({item:o})=>{await this.finalizeSessionWork(o.payload,o.id);},"telemetry.reconcile":async()=>{await this.flushTelemetry();}},afterComplete:({item:o,database:r})=>{o.sessionId&&this.enqueueLearningAnalysisIfReady(r,o.sessionId);}});}async start(){this.hostRuntime=await Co(this.projectRoot),mkdirSync(dirname(this.socketPath),{recursive:true,mode:448}),await this.cleanStaleStartupResources(),this.server=createServer(e=>this.handleConnection(e));try{await this.listen(),this.writePidFile(),un(this.projectRoot,process.pid);}catch(e){throw await this.closeServer(),this.cleanupOwnedResources(),e}if(this.server.on("error",e=>{console.error("[devflow-daemon] Server error:",e.message);}),console.error("[devflow-daemon] Listening on",this.socketPath),await this.telemetry.flushAndAggregate(),this.telemetryFlushTimer=setInterval(()=>{this.flushTelemetry();},Ya),this.telemetryFlushTimer.unref(),prepareEmbeddingModel().then(e=>{console.error(`[devflow-daemon] Embedding model ready (${e.source}) at ${e.cacheRoot}`);}).catch(e=>{console.error("[devflow-daemon] Embedding model unavailable; lexical retrieval remains active:",e.message);}),this.workRuntime.start(),this.initialSessionInput){let e=this.initialSessionInput;this.initialSessionInput=void 0,this.handleRequest({type:"session-start",input:e});}this.drainSessionStartSpool(),this.scheduleMemoryTurnSpoolDrain(0),this.scheduleSessionFinalizeSpoolDrain(0),this.resetIdleTimer();}handleConnection(e){let t="",o=false,r=false,i=0,s=Promise.resolve();e.setEncoding("utf8");let a=()=>{r||(r=true,clearTimeout(c),e.destroy());},c=setTimeout(()=>{a();},Ja).unref(),l=async d=>{if(!r){r=true,clearTimeout(c);try{await this.writeFrame(e,d);}catch{}finally{e.destroy();}}};e.on("data",d=>{if(r)return;t+=d;let u=t.split(`
|
|
29
|
+
`);if(t=u.pop()??"",Buffer.byteLength(t,"utf8")>Ho){a();return}if(u.length===0)return;let p=0;for(let h of u){let m=Buffer.byteLength(h,"utf8");if(m>Ho){a();return}p+=m+1;}if(i+p>Va){a();return}i+=p,s=s.then(async()=>{for(let h of u){if(r)return;if(!o){let m;try{m=JSON.parse(h);}catch{await l({error:"handshake_invalid"});return}if(m?.type!=="hello"||typeof m.rootPath!="string"){await l({error:"handshake_invalid"});return}if(m.rootPath!==this.projectRoot){await l({error:"handshake_root_mismatch",expected:this.projectRoot});return}o=true,clearTimeout(c),this.resetIdleTimer();continue}if(h.trim())try{let m=JSON.parse(h),y=await this.handleRequest(m);y!==null&&!r&&await this.writeFrame(e,y);}catch(m){r||await this.writeFrame(e,{error:m.message});}}}).catch(()=>{a();}).finally(()=>{i-=p;});}),e.on("close",()=>clearTimeout(c)),e.on("error",()=>{});}writeFrame(e,t){return new Promise((o,r)=>{if(e.destroyed||!e.writable){r(new Error("Socket is not writable"));return}let i=false,s=true,a=false,c=setTimeout(()=>{e.destroy(),d(new Error("Timed out writing daemon response"));},Ka),l=()=>{clearTimeout(c),e.off("close",u),e.off("error",p),e.off("drain",h);},d=y=>{a||!y&&(!i||!s)||(a=true,l(),y?r(y):o());},u=()=>d(new Error("Socket closed during write")),p=y=>d(y),h=()=>{s=true,d();};e.once("close",u),e.once("error",p),e.write(`${JSON.stringify(t)}
|
|
30
|
+
`,y=>{if(y){d(y);return}i=true,d();})||(s=false,e.once("drain",h));})}async cleanStaleStartupResources(){let e=this.getPathIdentity(this.socketPath);if(e){if(await this.isSocketAcceptingConnections())throw new Error(`Daemon socket already active for ${this.projectRoot}`);this.removePathIfOwned(this.socketPath,e,"stale socket");}let t=this.getPathIdentity(this.pidPath);t&&this.removePathIfOwned(this.pidPath,t,"stale PID file");}getPathIdentity(e){try{let t=lstatSync(e);return {dev:t.dev,ino:t.ino}}catch(t){if(t.code==="ENOENT")return null;throw t}}pathMatchesIdentity(e,t){if(!t)return false;try{let o=this.getPathIdentity(e);return o?.dev===t.dev&&o.ino===t.ino}catch(o){return console.error("[devflow-daemon] Failed to verify path ownership:",o.message),false}}writePidFile(){let e=openSync(this.pidPath,"wx",384);try{writeFileSync(e,`${process.pid}
|
|
31
|
+
`);let t=fstatSync(e);this.pidIdentity={dev:t.dev,ino:t.ino};}finally{closeSync(e);}}removePathIfOwned(e,t,o,r){try{return !this.pathMatchesIdentity(e,t)||r!==void 0&&readFileSync(e,"utf8")!==r||!this.pathMatchesIdentity(e,t)?!1:(unlinkSync(e),!0)}catch(i){return i.code!=="ENOENT"&&console.error(`[devflow-daemon] Failed to remove ${o}:`,i.message),false}}isSocketAcceptingConnections(){return new Promise((e,t)=>{let o=createConnection(this.socketPath),r=setTimeout(()=>{o.destroy(),t(new Error(`Timed out probing daemon socket ${this.socketPath}`));},Ga),i=s=>{clearTimeout(r),o.destroy(),e(s);};o.once("connect",()=>i(true)),o.once("error",s=>{let a=s.code;a==="ENOENT"||a==="ECONNREFUSED"?i(false):(clearTimeout(r),t(s));});})}listen(){return new Promise((e,t)=>{let o=this.server;if(!o){t(new Error("Daemon server is not initialized"));return}let r=s=>{o.off("listening",i),t(s);},i=()=>{o.off("error",r);try{let s=this.getPathIdentity(this.socketPath);if(!s)throw new Error(`Daemon socket missing after listen: ${this.socketPath}`);this.socketIdentity=s,e();}catch(s){t(s);}};o.once("error",r),o.once("listening",i),o.listen(this.socketPath);})}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,!(this.activeSessionIds.size>0)&&(this.idleTimer=setTimeout(()=>{console.error("[devflow-daemon] Idle timeout, exiting"),this.shutdown();},qa).unref());}async handleRequest(e){let t=this.hostRuntime;if(!t)return this.hookFailureResponse(e.type,{enabled:false,policy:"fail_open",reason:"host_adapter_not_ready",fallback:"host_event_continues_without_devflow_handler"});let o=Do(e.type,this.hookRuntime,t);if(!o.enabled)return this.hookFailureResponse(e.type,o);try{switch(e.type){case "pre-tool-use":return this.handlePreToolUse(e.input);case "post-tool-use":return await this.handlePostToolUse(e.input)??{status:"ok"};case "post-tool-use-failure":return await this.handlePostToolUseFailure(e.input)??{status:"ok"};case "stop":return Te("Stop",this.hookRuntime.acknowledgementBudgetMs,async()=>await this.handleStop(e.input??"")??{status:"ok"},()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"background_processing"}));case "memory-snapshot":return this.handleMemorySnapshot();case "session-start":return this.handleSessionStart(e.input??"");case "session-end":return Te("SessionEnd",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleSessionEnd(e.input??""),()=>({status:"degraded",reason:"hook_budget_exceeded",fallback:"durable_session_recovery"}));case "user-prompt-submit":return Te("UserPromptSubmit",this.hookRuntime.acknowledgementBudgetMs,()=>this.handleUserPromptSubmit(e.input),()=>({hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:"DevFlow background processing exceeded its acknowledgement budget; continue in degraded mode and do not claim an unreceipted memory save."}}));case "pre-compact":return this.handlePreCompact(e.input);default:return {error:"unknown request type"}}}catch(r){return this.hookFailureResponse(e.type,o,r)}}async drainSessionStartSpool(){for(;;){let e=vo(this.projectRoot);if(!e)return;try{let t=await this.handleRequest({type:"session-start",input:e.input});if(t&&"status"in t&&t.status==="degraded")throw new Error(`session_start_degraded:${String(t.reason??"unknown")}`);bo(e),console.error(`[devflow-daemon] SessionStart accepted from durable spool: ${e.receiptId}`);}catch(t){wo(e),console.error("[devflow-daemon] SessionStart spool deferred:",t.message);return}}}hookFailureResponse(e,t,o){let r=o instanceof Error?o.message:t.reason??"hook_handler_unavailable",i=t.fallback??(t.policy==="enqueue_and_open"?"durable_background_processing":"host_event_continues");return e==="pre-tool-use"?{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:t.policy==="fail_closed"?"deny":"allow",permissionDecisionReason:r,additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}.`}}:e==="user-prompt-submit"?{hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",additionalContext:`DevFlow hook degraded: ${r}; fallback=${i}. Do not claim unreceipted work completed.`}}:{status:"degraded",reason:r,fallback:i}}async handlePreToolUse(e){try{if(!e||e.trim()==="")return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};let t=JSON.parse(e);t.tool_input=ec(t.tool_name,t.tool_input,process.env,this.projectRoot);let o=this.trackSession(t.session_id),r="";if(t.tool_name==="Skill"){let S=t.tool_input?.skill,I=S?ve(S):null;I&&(r=this.startSkillExecution(o,I));}let i=this.runtimeStore.get(o);t.tool_name.startsWith("mcp__devflow__")&&(t.tool_input._devflow_session_id=o,t.tool_input._devflow_execution_id=i?.executionId??o,t.tool_use_id&&(t.tool_input._devflow_tool_use_id=t.tool_use_id));let s=t.tool_name.startsWith("mcp__"),a=s?t.tool_name.replace(/^mcp__[^_]+__/,""):void 0,c=new G(this.projectRoot,o,i?.executionId),l=c.getPhase(),d=ho({toolName:t.tool_name,toolInput:t.tool_input,projectRoot:this.projectRoot}),u=d?{permissionDecision:"deny",reason:d}:c.evaluate(t.tool_name,s),p;if(u.permissionDecision==="deny"?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:u.reason??"MCP context required"}}:u.additionalContext?p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:u.additionalContext}}:p={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}},r){let S=p.hookSpecificOutput,I=typeof S.additionalContext=="string"?S.additionalContext:"";S.additionalContext=I?`${I}
|
|
32
|
+
${r}`:r;}t.tool_name.startsWith("mcp__devflow__")&&(p.hookSpecificOutput.updatedInput=t.tool_input);let h={...t.tool_input};delete h._devflow_session_id,delete h._devflow_execution_id,delete h._devflow_tool_use_id;let m=i?.executionId??o,b={eventId:X(o,t.tool_use_id),executionId:m,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:t.tool_name,toolType:s?"mcp":t.tool_name==="Agent"?"subagent":"direct",isMcpTool:s,mcpToolName:a,mcpEnforced:s&&l==="context_gathering",mcpFallback:!s&&l==="context_gathering",kind:Za(t.tool_name),input:h,duration:0,blocked:p&&p.hookSpecificOutput?.permissionDecision==="deny"},_=await this.telemetry.sendEvent({...b,blockReason:b.blocked?d?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0,error:b.blocked?d?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED":void 0});return _&&!b.blocked&&(this.eventMap.push({toolName:t.tool_name,toolUseId:t.tool_use_id,eventId:_,sessionId:o,timestamp:b.timestamp}),this.noteTelemetryOperation()),_&&b.blocked&&await this.telemetry.completeEvent({eventId:_,sessionId:o,error:d?"DEVFLOW_CANONICAL_MEMORY_REQUIRED":"DEVFLOW_CONTEXT_REQUIRED",duration:Date.now()-b.timestamp,completedAt:Date.now()}),p}catch{return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}}trackSession(e){let t=e?.trim()||(this.activeSessionIds.size===1?[...this.activeSessionIds][0]:"");if(!t)throw new Error("session_id_required");return this.registerSession(t),t}registerSession(e){this.activeSessionIds.has(e)||(this.activeSessionIds.size===0&&ce(this.projectRoot,{bypassCount:0}),this.activeSessionIds.add(e),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.serverManager.addRef(e),this.telemetry.sendSessionStart(e,this.projectRoot,Date.now()).catch(()=>{})),this.runtimeStore.registerSession(e);}startSkillExecution(e,t,o){let r=this.runtimeStore.get(e)?.executionId,i=this.runtimeStore.startExecution(e,t,Gt(t));return i.executionId&&i.executionId!==r&&this.telemetry.sendExecutionStart(i.executionId,e,t,i.lastActivityAt,this.projectRoot,i.requiredMcpTools).catch(()=>{}),Bt(t,this.projectRoot,o)}async handleSessionStart(e){try{let t=JSON.parse(e);if(typeof t.session_id!="string"||!t.session_id.trim())return {error:"session_id_required"};let o=t.session_id.trim();this.registerSession(o);let r=`session-start:${createHash("sha256").update(`${this.projectRoot}\0${o}`).digest("hex").slice(0,24)}`,i=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),s="pending";try{s=i.enqueueWork({idempotencyKey:r,kind:"session.bootstrap",projectRoot:this.projectRoot,sessionId:o,payload:{sessionId:o}}).state;}finally{i.close();}return {status:s==="completed"?"completed":"accepted",receiptId:r,workState:s}}catch{return {error:"session_start_invalid"}}}popEventFromMap(e,t,o){let r=this.eventMap.filter(s=>s.toolName===e&&s.sessionId===t);if(r.length===0)return null;let i=o?r.find(s=>s.toolUseId===o):r.sort((s,a)=>s.timestamp-a.timestamp)[0];return i?(this.eventMap=this.eventMap.filter(s=>s.eventId!==i.eventId),i):null}enforcePostToolUse(e){if(!Qa[e])return null;let t=Math.floor(Date.now()/1e3),o=We(this.projectRoot,s=>t-(s.lastMcpCall??0)<30?s:{...s,bypassCount:(s.bypassCount??0)+1});if(!o.applied||!o.changed)return null;let r=o.receipt.bypassCount??0;if(r===1)return null;let i;switch(e){case "Agent":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u4F7F\u7528\u4E86 Agent \u5B50\u4EE3\u7406\u6267\u884C\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Bash":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Bash \u547D\u4EE4\u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Glob":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Glob \u5339\u914D\u6587\u4EF6\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "Grep":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86 Grep \u641C\u7D22\u4EE3\u7801\u3002\u4E0B\u6B21\u8BF7\u7528 get_project_context MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;case "WebSearch":case "WebFetch":i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u4F60\u521A\u624D\u7528\u4E86\u7F51\u7EDC\u641C\u7D22\u3002\u4E0B\u6B21\u8BF7\u7528 get_knowledge MCP \u5DE5\u5177\u66FF\u4EE3\u3002`;break;default:i=`\u7B2C ${r} \u6B21\u8FDD\u89C4\uFF1A\u8BF7\u4F7F\u7528 DevFlow MCP \u5DE5\u5177\u66FF\u4EE3\u76F4\u63A5\u8C03\u7528\u3002`;}return r>=3?i=`${i} \u5DF2\u8FBE\u5230\u6700\u5927\u8FDD\u89C4\u6B21\u6570\uFF0C\u540E\u7EED\u7ED5\u8FC7\u5C06\u88AB\u786C\u963B\u6B62\u3002`:r>=2?i=`${i} \u4E0B\u6B21\u8FDD\u89C4\u5C06\u88AB\u963B\u6B62\u3002`:i=`${i} \u8BF7\u7ACB\u5373\u7EA0\u6B63\u3002`,i}async handlePostToolUse(e){if(!e)return null;let t;try{t=JSON.parse(e);}catch{return null}let o=t.tool_name||"",r=t.tool_input||{},i=t.tool_response,s=this.trackSession(t.session_id);if(Oo({projectRoot:this.projectRoot,sessionId:s,executionId:this.runtimeStore.get(s)?.executionId,toolName:o,toolInput:r,toolUseId:t.tool_use_id}),o==="Skill"){let k=r?.skill,R=k?ve(k):null;R&&(this.startSkillExecution(s,R),ce(this.projectRoot,{lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}o.startsWith("mcp__")&&new G(this.projectRoot).recordMcpCall();let a=this.popEventFromMap(o,s,t.tool_use_id);if(a){let k=typeof i=="string"?i:JSON.stringify(i),R=k.length>5e3?{_truncated:true,_originalSize:k.length,text:k.slice(0,5e3)}:i,v=Date.now()-a.timestamp;await this.telemetry.completeEvent({eventId:a.eventId,sessionId:s,output:R,duration:v,completedAt:Date.now()})&&this.noteTelemetryOperation();}let c=typeof i=="object"&&i!==null?i:null,l=c?.exitCode,d=c?.stderr,u=/^\s*(ls|cat|pwd|cd|echo|head|tail|wc|which|whoami|date|env|printenv|id|hostname|uname)\b/,p=r.command||"",h=JSON.stringify(i),m=Buffer.byteLength(h,"utf8"),y=this.countResults(i),b,_,S=true;if(o.startsWith("mcp__"))b="mcp_call",_={mcpTool:o.replace(/^mcp__[^_]+__/,""),query:r.query??null,resultCount:y,resultSizeBytes:m};else if(o==="Read"||o==="Write"||o==="Edit")b=o==="Read"?"file_read":"file_write",_={filePath:r.file_path??null,fileContentSize:m};else if(o==="Bash"){let k=u.test(p),R=l!==void 0&&l!==0;S=!k||R,b=R?"bash_error":"bash_command",_={command:p||o,exitCode:l??null,stderr:d??null};}else o==="Agent"?(b="subagent",_={subagentType:r.subagent_type??null,description:typeof r.description=="string"?r.description.slice(0,200):null}):o==="WebSearch"||o==="WebFetch"?(b=o==="WebSearch"?"web_search":"web_fetch",_={query:typeof r.query=="string"?r.query.slice(0,200):null}):(S=false,b="tool_use",_={});if(S){let k={id:t.tool_use_id?`memory:${X(s,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:s,tool:o,kind:b,payload:_,command:p||void 0,exitCode:l,stderr:d??void 0,durationMs:0,createdAt:Date.now()};this.postMemoryEvent(k);}let I=Pn({toolName:o,toolResponse:i,sessionId:s,toolUseId:t.tool_use_id,runtimeStore:this.runtimeStore}),x=this.enforcePostToolUse(o);x&&console.error("[devflow-daemon] Enforcement:",x);let U=[I,x].filter(k=>!!k).join(`
|
|
32
33
|
|
|
33
|
-
`);return U?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:U}}:null}async handlePostToolUseFailure(e){let t;try{t=JSON.parse(e);}catch{return null}let o=this.trackSession(t.session_id),r=t.tool_name??"unknown",i=t.error??`${r} failed`,s=this.popEventFromMap(r,o,t.tool_use_id);if(s)await this.telemetry.completeEvent({eventId:s.eventId,sessionId:o,error:i,duration:Date.now()-s.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let a=X(o,t.tool_use_id);await this.telemetry.sendEvent({eventId:a,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:r.startsWith("mcp__")?r.replace(/^mcp__[^_]+__/,""):void 0,mcpEnforced:false,mcpFallback:false,kind:"error",input:t.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:t.tool_use_id?`memory:${X(o,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof t.tool_input?.command=="string"?t.tool_input.command:r,exitCode:-1,stderr:i,durationMs:s?Date.now()-s.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:t.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(e){if(!e)return 0;let t=e;if(typeof e=="string")try{t=JSON.parse(e);}catch{return 1}let o=t,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let l of r)Array.isArray(s[l])&&(c=true,a+=s[l].length);for(let[,l]of Object.entries(s))l&&typeof l=="object"&&!Array.isArray(l)&&(a+=this.countResults(l));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(e){
|
|
34
|
-
`)}:{}}}}async handlePreCompact(e){let t;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await
|
|
35
|
-
`);}};if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let n=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),e=new
|
|
34
|
+
`);return U?{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:U}}:null}async handlePostToolUseFailure(e){let t;try{t=JSON.parse(e);}catch{return null}let o=this.trackSession(t.session_id),r=t.tool_name??"unknown",i=t.error??`${r} failed`,s=this.popEventFromMap(r,o,t.tool_use_id);if(s)await this.telemetry.completeEvent({eventId:s.eventId,sessionId:o,error:i,duration:Date.now()-s.timestamp,completedAt:Date.now()})&&this.noteTelemetryOperation();else {let a=X(o,t.tool_use_id);await this.telemetry.sendEvent({eventId:a,executionId:this.runtimeStore.get(o)?.executionId??o,sessionId:o,projectRoot:this.projectRoot,toolUseId:t.tool_use_id,timestamp:Date.now(),toolName:r,toolType:r.startsWith("mcp__")?"mcp":"direct",isMcpTool:r.startsWith("mcp__"),mcpToolName:r.startsWith("mcp__")?r.replace(/^mcp__[^_]+__/,""):void 0,mcpEnforced:false,mcpFallback:false,kind:"error",input:t.tool_input??{},duration:0,error:i,blocked:false});}return this.postMemoryEvent({id:t.tool_use_id?`memory:${X(o,t.tool_use_id)}`:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o,tool:r,command:typeof t.tool_input?.command=="string"?t.tool_input.command:r,exitCode:-1,stderr:i,durationMs:s?Date.now()-s.timestamp:0,createdAt:Date.now(),kind:r==="Bash"?"bash_error":"tool_use",payload:{command:t.tool_input?.command??r,exitCode:-1,stderr:i}}),null}countResults(e){if(!e)return 0;let t=e;if(typeof e=="string")try{t=JSON.parse(e);}catch{return 1}let o=t,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],i=Array.isArray(o.data)?o.data:o.structuredContent??o;if(Array.isArray(i))return i.length;if(typeof i=="object"&&i!==null){let s=i,a=0,c=false;for(let l of r)Array.isArray(s[l])&&(c=true,a+=s[l].length);for(let[,l]of Object.entries(s))l&&typeof l=="object"&&!Array.isArray(l)&&(a+=this.countResults(l));return a>0?a:c?0:Object.keys(s).length>0?1:0}return 0}async postMemoryEvent(e){C(`/api/memory/session-events?rootPath=${encodeURIComponent(this.projectRoot)}`,e);try{await(await this.getMemoryGate()).recordEvent(e);}catch(t){console.error("[devflow-daemon] Local memory event write failed:",t.message);}}async getMemoryGate(){let e=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return this.memoryWarmup??=e.forceWarmUp().catch(t=>{throw this.memoryWarmup=null,t}),await this.memoryWarmup,e}async handleUserPromptSubmit(e){let t=[];try{let o=JSON.parse(e),r=typeof o.prompt=="string"?o.prompt:"",i=typeof o.session_id=="string"&&o.session_id.trim()?this.trackSession(o.session_id):null,s=Jn(r),a=!1;if(r.trim()&&i)try{let c=ut({projectRoot:this.projectRoot,sessionId:i,prompt:r});if(c){let l=c;if(c.explicitContent&&c.turn.status==="pending")try{l=await pt({projectRoot:this.projectRoot,payload:{operation:"commit_explicit",turnId:c.turn.turnId,eventId:c.turn.eventId,sessionId:i,prompt:r.trim().slice(0,4e3),explicitContent:c.explicitContent,createdAt:c.turn.createdAt},memory:await this.getMemoryGate()});}catch(d){console.error("[devflow-daemon] Explicit memory commit deferred:",d.message);}t.push(l.additionalContext),a=l.skipSkillRouting;}}catch(c){a=!!ye(r);try{let d=_o(this.projectRoot,{sessionId:i,prompt:r,createdAt:Date.now()});t.push(`DevFlow memory turn status=accepted; durable=true; receiptId=${d}; canonicalMemory=false; SQLite queue replay pending. Do not claim memory success without a canonical receipt.`),this.scheduleMemoryTurnSpoolDrain(250),console.error("[devflow-daemon] Memory turn spooled after database contention:",c.message);}catch(d){t.push("DevFlow memory turn status=degraded; durable=false; no canonical receipt exists. Do not claim memory success."),console.error("[devflow-daemon] Memory turn persistence unavailable:",d.message);}}if(i&&s&&!a){let c=this.startSkillExecution(i,s.skillName,r);c&&t.push(c);}}catch{}return {hookSpecificOutput:{hookEventName:"UserPromptSubmit",permissionDecision:"allow",...t.length?{additionalContext:t.join(`
|
|
35
|
+
`)}:{}}}}async handlePreCompact(e){let t;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}await this.flushTelemetry(),this.startExplicitIntentFlush(),await this.explicitIntentFlush;let o=await this.getMemoryGate(),r=await B({projectRoot:this.projectRoot,sessionId:t,trigger:"pre_compact",memory:o}),i=mn(r);return {hookSpecificOutput:{hookEventName:"PreCompact",...i?{additionalContext:i}:{}}}}async persistMemoryTurnItem(e){if(!e||typeof e!="object")throw new Error("memory_turn_payload_invalid");let t=e;if(t.operation!=="capture_prompt"&&t.operation!=="commit_explicit"||typeof t.turnId!="string"||typeof t.eventId!="string"||typeof t.sessionId!="string"||typeof t.prompt!="string"||typeof t.createdAt!="number")throw new Error("memory_turn_payload_invalid");await pt({projectRoot:this.projectRoot,payload:t,memory:await this.getMemoryGate()});}scheduleMemoryTurnSpoolDrain(e){this.memoryTurnSpoolTimer||(this.memoryTurnSpoolTimer=setTimeout(()=>{this.memoryTurnSpoolTimer=null,this.drainMemoryTurnSpool();},e),this.memoryTurnSpoolTimer.unref());}async drainMemoryTurnSpool(){for(;;){let e=ko(this.projectRoot);if(!e)return;try{ut({projectRoot:this.projectRoot,sessionId:e.payload.sessionId,prompt:e.payload.prompt}),Ro(e),this.workRuntime.drainOnce();}catch(t){Io(e),console.error("[devflow-daemon] Memory turn spool replay deferred:",t.message),this.scheduleMemoryTurnSpoolDrain(1e3);return}}}async bootstrapSessionWork(e){if(!e||typeof e!="object"||typeof e.sessionId!="string")throw new Error("session_bootstrap_payload_invalid");let t=e.sessionId,o=await this.getMemoryGate();await o.ensureSession(t,this.projectRoot,"Host session"),await o.releasePendingDistillLeases(t),await this.refreshMemorySnapshot("session_bootstrap");}noteTelemetryOperation(){this.successfulTelemetryOperations++,this.successfulTelemetryOperations>=Xa&&this.flushTelemetry();}async flushTelemetry(){this.successfulTelemetryOperations=0,await this.telemetry.flushAndAggregate();}startExplicitIntentFlush(){this.explicitIntentFlush||(this.explicitIntentFlush=this.flushExplicitMemoryIntents().finally(()=>{this.explicitIntentFlush=null;}));}async handleStop(e){let t=null,o=false,r;try{let i=JSON.parse(e);typeof i.session_id=="string"&&i.session_id.trim()&&(t=i.session_id.trim()),o=i.stop_hook_active===!0,typeof i.transcript_path=="string"&&i.transcript_path.trim()&&(r=i.transcript_path.trim());}catch{}if(t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null,this.startExplicitIntentFlush(),t){let i=Ao({projectRoot:this.projectRoot,sessionId:t,transcriptPath:r,stopHookActive:o,runtimeStore:this.runtimeStore});if(i.decision==="block_once")return {decision:"block",reason:i.additionalContext};let s=this.runtimeStore.completeExecution(t);if(s?.executionId){let a=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50}),c={};try{let l=a.listSessionMemoryTurnsForReconciliation(this.projectRoot,t);c={...Ke(l),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision};}finally{a.close();}await this.telemetry.sendExecutionComplete(s.executionId,"completed",Date.now(),c),this.deleteContextReceipt(t,s.executionId);}}return null}async flushExplicitMemoryIntents(){this.flushTelemetry();let e=qn(this.projectRoot);if(e)try{let t=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);await t.forceWarmUp();let o=!1;for(;e.intents.length>0;){let r=e.intents[0];if(r.turnId){let s=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{let a=s.getMemoryTurn(r.turnId);if(!a||a.status!=="pending"){console.error(`[devflow-daemon] Dropping stale legacy memory intent for ${r.turnId}: ${a?.status??"missing"}`),Ye(e);continue}}finally{s.close();}}let i=await t.saveExplicitMemoryIntent(r.content,r.sessionId,r.eventId);if(o=!0,r.turnId){let s=openGlobalDevFlowDatabase();try{s.commitMemoryTurn({turnId:r.turnId,receiptId:dt(r.turnId,"committed",[i.id]),memoryIds:[i.id],source:"explicit_intent",reason:"explicit_user_request_retry"});try{await t.enrichExplicitMemoryObservation(i.id);}catch(a){s.enqueueWork({idempotencyKey:`explicit-enrichment:${this.projectRoot}:${i.id}`,kind:"memory.explicit_enrichment",projectRoot:this.projectRoot,sessionId:r.sessionId,turnId:r.turnId,payload:{observationId:i.id},maxAttempts:20}),console.error("[devflow-daemon] Explicit memory enrichment deferred:",a.message);}}finally{s.close();}}Ye(e);}o&&await this.refreshMemorySnapshot("legacy_explicit_memory_commit");}catch(t){console.error("[devflow-daemon] Explicit memory intent save failed:",t.message);}}deleteContextReceipt(e,t){let o;try{o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250}),o.deleteContextReceipt(this.projectRoot,e,t);}catch{}finally{o?.close();}}async refreshMemorySnapshot(e){try{let t=loadConfig(this.projectRoot).sessionStart?.injectMemories??!0,o=this.explicitMemoryGate??=new MemoryGate(this.projectRoot);return await Re({projectRoot:this.projectRoot,memory:o,injectConfig:t,reason:e})}catch(t){return console.error("[devflow-daemon] Memory snapshot refresh degraded:",t.message),ct({projectRoot:this.projectRoot,reason:e,load:async()=>{throw t}})}}async handleMemorySnapshot(){let e=await this.refreshMemorySnapshot("memory_snapshot_request"),{snapshot:t}=e;return {status:t.status==="ready"||t.status==="disabled"?"ok":t.status,enabled:t.status!=="disabled",markdown:t.markdown,memoryIds:t.memoryIds,memoryCount:t.memoryIds.length,conflicts:t.conflicts,snapshot:t,persisted:e.persisted}}async handleSessionEnd(e){let t=null;try{let s=JSON.parse(e);typeof s.session_id=="string"&&s.session_id.trim()&&(t=s.session_id.trim());}catch{}t??=this.activeSessionIds.size===1?[...this.activeSessionIds][0]:null;let o=t===null?this.activeSessionIds.size<=1:this.activeSessionIds.size<=1&&this.activeSessionIds.has(t),r=t?this.runtimeStore.get(t)?.executionId:void 0,i=ge(e,this.projectRoot,o,r);return i?.workState==="spooled"&&this.scheduleSessionFinalizeSpoolDrain(250),t&&(this.serverManager.removeRef(t),this.activeSessionIds.delete(t),this.eventMap=this.eventMap.filter(s=>s.sessionId!==t)),this.activeSessionIds.size===0&&i?.workState!=="spooled"?setImmediate(()=>{this.workRuntime.drainOnce().finally(()=>{this.shutdown();});}):this.resetIdleTimer(),i??{status:"ok"}}async finalizeSessionWork(e,t){if(!e||typeof e!="object")throw new Error("session_finalize_payload_invalid");let o=e;if(typeof o.inputJson!="string"||typeof o.sessionId!="string")throw new Error("session_finalize_payload_invalid");let r=await this.getMemoryGate();await Hn(o.inputJson,this.projectRoot,o.cleanupSharedState!==false,{telemetry:this.telemetry,memory:r,executionId:o.executionId});try{await this.refreshMemorySnapshot("session_finalization");}catch(s){console.error("[devflow-daemon] Session finalization snapshot refresh degraded:",s.message);}let i=openGlobalDevFlowDatabase();try{i.completeSessionClosure(this.projectRoot,o.sessionId,t);}finally{i.close();}}enqueueLearningAnalysisIfReady(e,t){if(resolveCapabilityRollout(this.projectRoot).config.learningOverlays==="off")return;let r=e.getSessionClosure(this.projectRoot,t);if(!r||r.state!=="closed"||r.pendingWorkCount!==0||e.listSessionObligations(this.projectRoot,t).some(c=>c.state==="open"||c.state==="degraded"))return;let s=e.getLatestSkillExecutionForSession(t);if(s&&s.status==="running")return;let a=tc(this.projectRoot);e.enqueueWork({idempotencyKey:`learning-analysis:${r.receiptId}:${a}`,kind:"learning.analyze_session",projectRoot:this.projectRoot,sessionId:t,payload:{projectRoot:this.projectRoot,sessionId:t,executionId:s?.executionId,closureReceipt:r.receiptId,projectRevision:a,createdAt:Date.now()},maxAttempts:5});}scheduleSessionFinalizeSpoolDrain(e){this.sessionFinalizeSpoolTimer||(this.sessionFinalizeSpoolTimer=setTimeout(()=>{this.sessionFinalizeSpoolTimer=null,this.drainSessionFinalizeSpool();},e),this.sessionFinalizeSpoolTimer.unref());}async drainSessionFinalizeSpool(){for(;;){let e=Mn(this.projectRoot);if(!e)return;try{if(!ge(e.payload.inputJson,this.projectRoot,e.payload.cleanupSharedState,e.payload.executionId,!1))throw new Error("session_finalize_spool_rejected");Tn(e),this.workRuntime.drainOnce();}catch(t){Cn(e),console.error("[devflow-daemon] Session finalize spool replay deferred:",t.message),this.scheduleSessionFinalizeSpoolDrain(1e3);return}}}shutdown(){return this.shutdownPromise?this.shutdownPromise:(this.shutdownPromise=this.performShutdown(),this.shutdownPromise)}async performShutdown(){this.workRuntime.stop(),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.telemetryFlushTimer&&(clearInterval(this.telemetryFlushTimer),this.telemetryFlushTimer=null),this.memoryTurnSpoolTimer&&(clearTimeout(this.memoryTurnSpoolTimer),this.memoryTurnSpoolTimer=null),this.sessionFinalizeSpoolTimer&&(clearTimeout(this.sessionFinalizeSpoolTimer),this.sessionFinalizeSpoolTimer=null),await this.flushTelemetry(),await this.closeServer(),this.cleanupOwnedResources(),await this.serverManager.stop(),await this.explicitIntentFlush,this.explicitMemoryGate?.close(),this.explicitMemoryGate=null,this.telemetry.close(),process.exit(0);}closeServer(){let e=this.server;return !e||!e.listening||!this.pathMatchesIdentity(this.socketPath,this.socketIdentity)?Promise.resolve():(this.server=null,new Promise(t=>{let o=false,r=()=>{o||(o=true,clearTimeout(i),t());},i=setTimeout(r,Ba);e.close(r);}))}cleanupOwnedResources(){try{pn(this.projectRoot,process.pid);}catch(e){console.error("[devflow-daemon] Failed to unregister:",e.message);}this.removePathIfOwned(this.socketPath,this.socketIdentity,"socket"),this.removePathIfOwned(this.pidPath,this.pidIdentity,"PID file",`${process.pid}
|
|
36
|
+
`);}};function tc(n){try{return execFileSync("git",["rev-parse","HEAD"],{cwd:n,encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return `unversioned:${createHash("sha256").update(n).digest("hex").slice(0,16)}`}}if(process.env.DEVFLOW_HOOK_DAEMON_DISABLE_AUTOSTART!=="1"){let n=process.argv[2]||process.env.CLAUDE_PROJECT_DIR||process.cwd(),e=new xt(n,process.argv[3]);process.once("SIGTERM",()=>{e.shutdown();}),process.once("SIGINT",()=>{e.shutdown();}),e.start().catch(t=>{console.error("[devflow-daemon] Failed to start:",t),process.exit(1);});}export{xt as HookDaemon,ec as injectProjectRootIfMissing};
|